1bf215546Sopenharmony_ci/* 2bf215546Sopenharmony_ci * Mesa 3-D graphics library 3bf215546Sopenharmony_ci * 4bf215546Sopenharmony_ci * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. 5bf215546Sopenharmony_ci * 6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a 7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"), 8bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation 9bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the 11bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions: 12bf215546Sopenharmony_ci * 13bf215546Sopenharmony_ci * The above copyright notice and this permission notice shall be included 14bf215546Sopenharmony_ci * in all copies or substantial portions of the Software. 15bf215546Sopenharmony_ci * 16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20bf215546Sopenharmony_ci * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21bf215546Sopenharmony_ci * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22bf215546Sopenharmony_ci * OTHER DEALINGS IN THE SOFTWARE. 23bf215546Sopenharmony_ci */ 24bf215546Sopenharmony_ci 25bf215546Sopenharmony_ci 26bf215546Sopenharmony_ci/** 27bf215546Sopenharmony_ci * \file mipmap.c mipmap generation and teximage resizing functions. 28bf215546Sopenharmony_ci */ 29bf215546Sopenharmony_ci 30bf215546Sopenharmony_ci#include "errors.h" 31bf215546Sopenharmony_ci 32bf215546Sopenharmony_ci#include "formats.h" 33bf215546Sopenharmony_ci#include "glformats.h" 34bf215546Sopenharmony_ci#include "mipmap.h" 35bf215546Sopenharmony_ci#include "mtypes.h" 36bf215546Sopenharmony_ci#include "teximage.h" 37bf215546Sopenharmony_ci#include "texobj.h" 38bf215546Sopenharmony_ci#include "texstore.h" 39bf215546Sopenharmony_ci#include "image.h" 40bf215546Sopenharmony_ci#include "macros.h" 41bf215546Sopenharmony_ci#include "util/half_float.h" 42bf215546Sopenharmony_ci#include "util/format_rgb9e5.h" 43bf215546Sopenharmony_ci#include "util/format_r11g11b10f.h" 44bf215546Sopenharmony_ci 45bf215546Sopenharmony_ci#include "state_tracker/st_cb_texture.h" 46bf215546Sopenharmony_ci 47bf215546Sopenharmony_ci/** 48bf215546Sopenharmony_ci * Compute the expected number of mipmap levels in the texture given 49bf215546Sopenharmony_ci * the width/height/depth of the base image and the GL_TEXTURE_BASE_LEVEL/ 50bf215546Sopenharmony_ci * GL_TEXTURE_MAX_LEVEL settings. This will tell us how many mipmap 51bf215546Sopenharmony_ci * levels should be generated. 52bf215546Sopenharmony_ci */ 53bf215546Sopenharmony_ciunsigned 54bf215546Sopenharmony_ci_mesa_compute_num_levels(struct gl_context *ctx, 55bf215546Sopenharmony_ci struct gl_texture_object *texObj, 56bf215546Sopenharmony_ci GLenum target) 57bf215546Sopenharmony_ci{ 58bf215546Sopenharmony_ci const struct gl_texture_image *baseImage; 59bf215546Sopenharmony_ci GLuint numLevels; 60bf215546Sopenharmony_ci 61bf215546Sopenharmony_ci baseImage = _mesa_get_tex_image(ctx, texObj, target, texObj->Attrib.BaseLevel); 62bf215546Sopenharmony_ci 63bf215546Sopenharmony_ci numLevels = texObj->Attrib.BaseLevel + baseImage->MaxNumLevels; 64bf215546Sopenharmony_ci numLevels = MIN2(numLevels, (GLuint) texObj->Attrib.MaxLevel + 1); 65bf215546Sopenharmony_ci if (texObj->Immutable) 66bf215546Sopenharmony_ci numLevels = MIN2(numLevels, texObj->Attrib.NumLevels); 67bf215546Sopenharmony_ci assert(numLevels >= 1); 68bf215546Sopenharmony_ci 69bf215546Sopenharmony_ci return numLevels; 70bf215546Sopenharmony_ci} 71bf215546Sopenharmony_ci 72bf215546Sopenharmony_cistatic GLint 73bf215546Sopenharmony_cibytes_per_pixel(GLenum datatype, GLuint comps) 74bf215546Sopenharmony_ci{ 75bf215546Sopenharmony_ci GLint b; 76bf215546Sopenharmony_ci 77bf215546Sopenharmony_ci if (datatype == GL_UNSIGNED_INT_8_24_REV_MESA || 78bf215546Sopenharmony_ci datatype == GL_UNSIGNED_INT_24_8_MESA) 79bf215546Sopenharmony_ci return 4; 80bf215546Sopenharmony_ci 81bf215546Sopenharmony_ci b = _mesa_sizeof_packed_type(datatype); 82bf215546Sopenharmony_ci assert(b >= 0); 83bf215546Sopenharmony_ci 84bf215546Sopenharmony_ci if (_mesa_type_is_packed(datatype)) 85bf215546Sopenharmony_ci return b; 86bf215546Sopenharmony_ci else 87bf215546Sopenharmony_ci return b * comps; 88bf215546Sopenharmony_ci} 89bf215546Sopenharmony_ci 90bf215546Sopenharmony_ci 91bf215546Sopenharmony_ci/** 92bf215546Sopenharmony_ci * \name Support macros for do_row and do_row_3d 93bf215546Sopenharmony_ci * 94bf215546Sopenharmony_ci * The macro madness is here for two reasons. First, it compacts the code 95bf215546Sopenharmony_ci * slightly. Second, it makes it much easier to adjust the specifics of the 96bf215546Sopenharmony_ci * filter to tune the rounding characteristics. 97bf215546Sopenharmony_ci */ 98bf215546Sopenharmony_ci/*@{*/ 99bf215546Sopenharmony_ci#define DECLARE_ROW_POINTERS(t, e) \ 100bf215546Sopenharmony_ci const t(*rowA)[e] = (const t(*)[e]) srcRowA; \ 101bf215546Sopenharmony_ci const t(*rowB)[e] = (const t(*)[e]) srcRowB; \ 102bf215546Sopenharmony_ci const t(*rowC)[e] = (const t(*)[e]) srcRowC; \ 103bf215546Sopenharmony_ci const t(*rowD)[e] = (const t(*)[e]) srcRowD; \ 104bf215546Sopenharmony_ci t(*dst)[e] = (t(*)[e]) dstRow 105bf215546Sopenharmony_ci 106bf215546Sopenharmony_ci#define DECLARE_ROW_POINTERS0(t) \ 107bf215546Sopenharmony_ci const t *rowA = (const t *) srcRowA; \ 108bf215546Sopenharmony_ci const t *rowB = (const t *) srcRowB; \ 109bf215546Sopenharmony_ci const t *rowC = (const t *) srcRowC; \ 110bf215546Sopenharmony_ci const t *rowD = (const t *) srcRowD; \ 111bf215546Sopenharmony_ci t *dst = (t *) dstRow 112bf215546Sopenharmony_ci 113bf215546Sopenharmony_ci#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \ 114bf215546Sopenharmony_ci ((unsigned) Aj + (unsigned) Ak \ 115bf215546Sopenharmony_ci + (unsigned) Bj + (unsigned) Bk \ 116bf215546Sopenharmony_ci + (unsigned) Cj + (unsigned) Ck \ 117bf215546Sopenharmony_ci + (unsigned) Dj + (unsigned) Dk \ 118bf215546Sopenharmony_ci + 4) >> 3 119bf215546Sopenharmony_ci 120bf215546Sopenharmony_ci#define FILTER_3D(e) \ 121bf215546Sopenharmony_ci do { \ 122bf215546Sopenharmony_ci dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \ 123bf215546Sopenharmony_ci rowB[j][e], rowB[k][e], \ 124bf215546Sopenharmony_ci rowC[j][e], rowC[k][e], \ 125bf215546Sopenharmony_ci rowD[j][e], rowD[k][e]); \ 126bf215546Sopenharmony_ci } while(0) 127bf215546Sopenharmony_ci 128bf215546Sopenharmony_ci#define FILTER_SUM_3D_SIGNED(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \ 129bf215546Sopenharmony_ci (Aj + Ak \ 130bf215546Sopenharmony_ci + Bj + Bk \ 131bf215546Sopenharmony_ci + Cj + Ck \ 132bf215546Sopenharmony_ci + Dj + Dk \ 133bf215546Sopenharmony_ci + 4) / 8 134bf215546Sopenharmony_ci 135bf215546Sopenharmony_ci#define FILTER_3D_SIGNED(e) \ 136bf215546Sopenharmony_ci do { \ 137bf215546Sopenharmony_ci dst[i][e] = FILTER_SUM_3D_SIGNED(rowA[j][e], rowA[k][e], \ 138bf215546Sopenharmony_ci rowB[j][e], rowB[k][e], \ 139bf215546Sopenharmony_ci rowC[j][e], rowC[k][e], \ 140bf215546Sopenharmony_ci rowD[j][e], rowD[k][e]); \ 141bf215546Sopenharmony_ci } while(0) 142bf215546Sopenharmony_ci 143bf215546Sopenharmony_ci#define FILTER_F_3D(e) \ 144bf215546Sopenharmony_ci do { \ 145bf215546Sopenharmony_ci dst[i][e] = (rowA[j][e] + rowA[k][e] \ 146bf215546Sopenharmony_ci + rowB[j][e] + rowB[k][e] \ 147bf215546Sopenharmony_ci + rowC[j][e] + rowC[k][e] \ 148bf215546Sopenharmony_ci + rowD[j][e] + rowD[k][e]) * 0.125F; \ 149bf215546Sopenharmony_ci } while(0) 150bf215546Sopenharmony_ci 151bf215546Sopenharmony_ci#define FILTER_HF_3D(e) \ 152bf215546Sopenharmony_ci do { \ 153bf215546Sopenharmony_ci const GLfloat aj = _mesa_half_to_float(rowA[j][e]); \ 154bf215546Sopenharmony_ci const GLfloat ak = _mesa_half_to_float(rowA[k][e]); \ 155bf215546Sopenharmony_ci const GLfloat bj = _mesa_half_to_float(rowB[j][e]); \ 156bf215546Sopenharmony_ci const GLfloat bk = _mesa_half_to_float(rowB[k][e]); \ 157bf215546Sopenharmony_ci const GLfloat cj = _mesa_half_to_float(rowC[j][e]); \ 158bf215546Sopenharmony_ci const GLfloat ck = _mesa_half_to_float(rowC[k][e]); \ 159bf215546Sopenharmony_ci const GLfloat dj = _mesa_half_to_float(rowD[j][e]); \ 160bf215546Sopenharmony_ci const GLfloat dk = _mesa_half_to_float(rowD[k][e]); \ 161bf215546Sopenharmony_ci dst[i][e] = _mesa_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \ 162bf215546Sopenharmony_ci * 0.125F); \ 163bf215546Sopenharmony_ci } while(0) 164bf215546Sopenharmony_ci/*@}*/ 165bf215546Sopenharmony_ci 166bf215546Sopenharmony_ci 167bf215546Sopenharmony_ci/** 168bf215546Sopenharmony_ci * Average together two rows of a source image to produce a single new 169bf215546Sopenharmony_ci * row in the dest image. It's legal for the two source rows to point 170bf215546Sopenharmony_ci * to the same data. The source width must be equal to either the 171bf215546Sopenharmony_ci * dest width or two times the dest width. 172bf215546Sopenharmony_ci * \param datatype GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc. 173bf215546Sopenharmony_ci * \param comps number of components per pixel (1..4) 174bf215546Sopenharmony_ci */ 175bf215546Sopenharmony_cistatic void 176bf215546Sopenharmony_cido_row(GLenum datatype, GLuint comps, GLint srcWidth, 177bf215546Sopenharmony_ci const GLvoid *srcRowA, const GLvoid *srcRowB, 178bf215546Sopenharmony_ci GLint dstWidth, GLvoid *dstRow) 179bf215546Sopenharmony_ci{ 180bf215546Sopenharmony_ci const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; 181bf215546Sopenharmony_ci const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; 182bf215546Sopenharmony_ci 183bf215546Sopenharmony_ci assert(comps >= 1); 184bf215546Sopenharmony_ci assert(comps <= 4); 185bf215546Sopenharmony_ci 186bf215546Sopenharmony_ci /* This assertion is no longer valid with non-power-of-2 textures 187bf215546Sopenharmony_ci assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth); 188bf215546Sopenharmony_ci */ 189bf215546Sopenharmony_ci 190bf215546Sopenharmony_ci if (datatype == GL_UNSIGNED_BYTE && comps == 4) { 191bf215546Sopenharmony_ci GLuint i, j, k; 192bf215546Sopenharmony_ci const GLubyte(*rowA)[4] = (const GLubyte(*)[4]) srcRowA; 193bf215546Sopenharmony_ci const GLubyte(*rowB)[4] = (const GLubyte(*)[4]) srcRowB; 194bf215546Sopenharmony_ci GLubyte(*dst)[4] = (GLubyte(*)[4]) dstRow; 195bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 196bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 197bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 198bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 199bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 200bf215546Sopenharmony_ci dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; 201bf215546Sopenharmony_ci } 202bf215546Sopenharmony_ci } 203bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_BYTE && comps == 3) { 204bf215546Sopenharmony_ci GLuint i, j, k; 205bf215546Sopenharmony_ci const GLubyte(*rowA)[3] = (const GLubyte(*)[3]) srcRowA; 206bf215546Sopenharmony_ci const GLubyte(*rowB)[3] = (const GLubyte(*)[3]) srcRowB; 207bf215546Sopenharmony_ci GLubyte(*dst)[3] = (GLubyte(*)[3]) dstRow; 208bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 209bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 210bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 211bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 212bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 213bf215546Sopenharmony_ci } 214bf215546Sopenharmony_ci } 215bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_BYTE && comps == 2) { 216bf215546Sopenharmony_ci GLuint i, j, k; 217bf215546Sopenharmony_ci const GLubyte(*rowA)[2] = (const GLubyte(*)[2]) srcRowA; 218bf215546Sopenharmony_ci const GLubyte(*rowB)[2] = (const GLubyte(*)[2]) srcRowB; 219bf215546Sopenharmony_ci GLubyte(*dst)[2] = (GLubyte(*)[2]) dstRow; 220bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 221bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 222bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2; 223bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2; 224bf215546Sopenharmony_ci } 225bf215546Sopenharmony_ci } 226bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_BYTE && comps == 1) { 227bf215546Sopenharmony_ci GLuint i, j, k; 228bf215546Sopenharmony_ci const GLubyte *rowA = (const GLubyte *) srcRowA; 229bf215546Sopenharmony_ci const GLubyte *rowB = (const GLubyte *) srcRowB; 230bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dstRow; 231bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 232bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 233bf215546Sopenharmony_ci dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2; 234bf215546Sopenharmony_ci } 235bf215546Sopenharmony_ci } 236bf215546Sopenharmony_ci 237bf215546Sopenharmony_ci else if (datatype == GL_BYTE && comps == 4) { 238bf215546Sopenharmony_ci GLuint i, j, k; 239bf215546Sopenharmony_ci const GLbyte(*rowA)[4] = (const GLbyte(*)[4]) srcRowA; 240bf215546Sopenharmony_ci const GLbyte(*rowB)[4] = (const GLbyte(*)[4]) srcRowB; 241bf215546Sopenharmony_ci GLbyte(*dst)[4] = (GLbyte(*)[4]) dstRow; 242bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 243bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 244bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 245bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 246bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 247bf215546Sopenharmony_ci dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; 248bf215546Sopenharmony_ci } 249bf215546Sopenharmony_ci } 250bf215546Sopenharmony_ci else if (datatype == GL_BYTE && comps == 3) { 251bf215546Sopenharmony_ci GLuint i, j, k; 252bf215546Sopenharmony_ci const GLbyte(*rowA)[3] = (const GLbyte(*)[3]) srcRowA; 253bf215546Sopenharmony_ci const GLbyte(*rowB)[3] = (const GLbyte(*)[3]) srcRowB; 254bf215546Sopenharmony_ci GLbyte(*dst)[3] = (GLbyte(*)[3]) dstRow; 255bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 256bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 257bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 258bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 259bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 260bf215546Sopenharmony_ci } 261bf215546Sopenharmony_ci } 262bf215546Sopenharmony_ci else if (datatype == GL_BYTE && comps == 2) { 263bf215546Sopenharmony_ci GLuint i, j, k; 264bf215546Sopenharmony_ci const GLbyte(*rowA)[2] = (const GLbyte(*)[2]) srcRowA; 265bf215546Sopenharmony_ci const GLbyte(*rowB)[2] = (const GLbyte(*)[2]) srcRowB; 266bf215546Sopenharmony_ci GLbyte(*dst)[2] = (GLbyte(*)[2]) dstRow; 267bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 268bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 269bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 270bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 271bf215546Sopenharmony_ci } 272bf215546Sopenharmony_ci } 273bf215546Sopenharmony_ci else if (datatype == GL_BYTE && comps == 1) { 274bf215546Sopenharmony_ci GLuint i, j, k; 275bf215546Sopenharmony_ci const GLbyte *rowA = (const GLbyte *) srcRowA; 276bf215546Sopenharmony_ci const GLbyte *rowB = (const GLbyte *) srcRowB; 277bf215546Sopenharmony_ci GLbyte *dst = (GLbyte *) dstRow; 278bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 279bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 280bf215546Sopenharmony_ci dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 281bf215546Sopenharmony_ci } 282bf215546Sopenharmony_ci } 283bf215546Sopenharmony_ci 284bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT && comps == 4) { 285bf215546Sopenharmony_ci GLuint i, j, k; 286bf215546Sopenharmony_ci const GLushort(*rowA)[4] = (const GLushort(*)[4]) srcRowA; 287bf215546Sopenharmony_ci const GLushort(*rowB)[4] = (const GLushort(*)[4]) srcRowB; 288bf215546Sopenharmony_ci GLushort(*dst)[4] = (GLushort(*)[4]) dstRow; 289bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 290bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 291bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 292bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 293bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 294bf215546Sopenharmony_ci dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; 295bf215546Sopenharmony_ci } 296bf215546Sopenharmony_ci } 297bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT && comps == 3) { 298bf215546Sopenharmony_ci GLuint i, j, k; 299bf215546Sopenharmony_ci const GLushort(*rowA)[3] = (const GLushort(*)[3]) srcRowA; 300bf215546Sopenharmony_ci const GLushort(*rowB)[3] = (const GLushort(*)[3]) srcRowB; 301bf215546Sopenharmony_ci GLushort(*dst)[3] = (GLushort(*)[3]) dstRow; 302bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 303bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 304bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 305bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 306bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 307bf215546Sopenharmony_ci } 308bf215546Sopenharmony_ci } 309bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT && comps == 2) { 310bf215546Sopenharmony_ci GLuint i, j, k; 311bf215546Sopenharmony_ci const GLushort(*rowA)[2] = (const GLushort(*)[2]) srcRowA; 312bf215546Sopenharmony_ci const GLushort(*rowB)[2] = (const GLushort(*)[2]) srcRowB; 313bf215546Sopenharmony_ci GLushort(*dst)[2] = (GLushort(*)[2]) dstRow; 314bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 315bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 316bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 317bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 318bf215546Sopenharmony_ci } 319bf215546Sopenharmony_ci } 320bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT && comps == 1) { 321bf215546Sopenharmony_ci GLuint i, j, k; 322bf215546Sopenharmony_ci const GLushort *rowA = (const GLushort *) srcRowA; 323bf215546Sopenharmony_ci const GLushort *rowB = (const GLushort *) srcRowB; 324bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dstRow; 325bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 326bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 327bf215546Sopenharmony_ci dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 328bf215546Sopenharmony_ci } 329bf215546Sopenharmony_ci } 330bf215546Sopenharmony_ci 331bf215546Sopenharmony_ci else if (datatype == GL_SHORT && comps == 4) { 332bf215546Sopenharmony_ci GLuint i, j, k; 333bf215546Sopenharmony_ci const GLshort(*rowA)[4] = (const GLshort(*)[4]) srcRowA; 334bf215546Sopenharmony_ci const GLshort(*rowB)[4] = (const GLshort(*)[4]) srcRowB; 335bf215546Sopenharmony_ci GLshort(*dst)[4] = (GLshort(*)[4]) dstRow; 336bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 337bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 338bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 339bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 340bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 341bf215546Sopenharmony_ci dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4; 342bf215546Sopenharmony_ci } 343bf215546Sopenharmony_ci } 344bf215546Sopenharmony_ci else if (datatype == GL_SHORT && comps == 3) { 345bf215546Sopenharmony_ci GLuint i, j, k; 346bf215546Sopenharmony_ci const GLshort(*rowA)[3] = (const GLshort(*)[3]) srcRowA; 347bf215546Sopenharmony_ci const GLshort(*rowB)[3] = (const GLshort(*)[3]) srcRowB; 348bf215546Sopenharmony_ci GLshort(*dst)[3] = (GLshort(*)[3]) dstRow; 349bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 350bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 351bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 352bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 353bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4; 354bf215546Sopenharmony_ci } 355bf215546Sopenharmony_ci } 356bf215546Sopenharmony_ci else if (datatype == GL_SHORT && comps == 2) { 357bf215546Sopenharmony_ci GLuint i, j, k; 358bf215546Sopenharmony_ci const GLshort(*rowA)[2] = (const GLshort(*)[2]) srcRowA; 359bf215546Sopenharmony_ci const GLshort(*rowB)[2] = (const GLshort(*)[2]) srcRowB; 360bf215546Sopenharmony_ci GLshort(*dst)[2] = (GLshort(*)[2]) dstRow; 361bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 362bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 363bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4; 364bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4; 365bf215546Sopenharmony_ci } 366bf215546Sopenharmony_ci } 367bf215546Sopenharmony_ci else if (datatype == GL_SHORT && comps == 1) { 368bf215546Sopenharmony_ci GLuint i, j, k; 369bf215546Sopenharmony_ci const GLshort *rowA = (const GLshort *) srcRowA; 370bf215546Sopenharmony_ci const GLshort *rowB = (const GLshort *) srcRowB; 371bf215546Sopenharmony_ci GLshort *dst = (GLshort *) dstRow; 372bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 373bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 374bf215546Sopenharmony_ci dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4; 375bf215546Sopenharmony_ci } 376bf215546Sopenharmony_ci } 377bf215546Sopenharmony_ci 378bf215546Sopenharmony_ci else if (datatype == GL_FLOAT && comps == 4) { 379bf215546Sopenharmony_ci GLuint i, j, k; 380bf215546Sopenharmony_ci const GLfloat(*rowA)[4] = (const GLfloat(*)[4]) srcRowA; 381bf215546Sopenharmony_ci const GLfloat(*rowB)[4] = (const GLfloat(*)[4]) srcRowB; 382bf215546Sopenharmony_ci GLfloat(*dst)[4] = (GLfloat(*)[4]) dstRow; 383bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 384bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 385bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + 386bf215546Sopenharmony_ci rowB[j][0] + rowB[k][0]) * 0.25F; 387bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + 388bf215546Sopenharmony_ci rowB[j][1] + rowB[k][1]) * 0.25F; 389bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + 390bf215546Sopenharmony_ci rowB[j][2] + rowB[k][2]) * 0.25F; 391bf215546Sopenharmony_ci dst[i][3] = (rowA[j][3] + rowA[k][3] + 392bf215546Sopenharmony_ci rowB[j][3] + rowB[k][3]) * 0.25F; 393bf215546Sopenharmony_ci } 394bf215546Sopenharmony_ci } 395bf215546Sopenharmony_ci else if (datatype == GL_FLOAT && comps == 3) { 396bf215546Sopenharmony_ci GLuint i, j, k; 397bf215546Sopenharmony_ci const GLfloat(*rowA)[3] = (const GLfloat(*)[3]) srcRowA; 398bf215546Sopenharmony_ci const GLfloat(*rowB)[3] = (const GLfloat(*)[3]) srcRowB; 399bf215546Sopenharmony_ci GLfloat(*dst)[3] = (GLfloat(*)[3]) dstRow; 400bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 401bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 402bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + 403bf215546Sopenharmony_ci rowB[j][0] + rowB[k][0]) * 0.25F; 404bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + 405bf215546Sopenharmony_ci rowB[j][1] + rowB[k][1]) * 0.25F; 406bf215546Sopenharmony_ci dst[i][2] = (rowA[j][2] + rowA[k][2] + 407bf215546Sopenharmony_ci rowB[j][2] + rowB[k][2]) * 0.25F; 408bf215546Sopenharmony_ci } 409bf215546Sopenharmony_ci } 410bf215546Sopenharmony_ci else if (datatype == GL_FLOAT && comps == 2) { 411bf215546Sopenharmony_ci GLuint i, j, k; 412bf215546Sopenharmony_ci const GLfloat(*rowA)[2] = (const GLfloat(*)[2]) srcRowA; 413bf215546Sopenharmony_ci const GLfloat(*rowB)[2] = (const GLfloat(*)[2]) srcRowB; 414bf215546Sopenharmony_ci GLfloat(*dst)[2] = (GLfloat(*)[2]) dstRow; 415bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 416bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 417bf215546Sopenharmony_ci dst[i][0] = (rowA[j][0] + rowA[k][0] + 418bf215546Sopenharmony_ci rowB[j][0] + rowB[k][0]) * 0.25F; 419bf215546Sopenharmony_ci dst[i][1] = (rowA[j][1] + rowA[k][1] + 420bf215546Sopenharmony_ci rowB[j][1] + rowB[k][1]) * 0.25F; 421bf215546Sopenharmony_ci } 422bf215546Sopenharmony_ci } 423bf215546Sopenharmony_ci else if (datatype == GL_FLOAT && comps == 1) { 424bf215546Sopenharmony_ci GLuint i, j, k; 425bf215546Sopenharmony_ci const GLfloat *rowA = (const GLfloat *) srcRowA; 426bf215546Sopenharmony_ci const GLfloat *rowB = (const GLfloat *) srcRowB; 427bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dstRow; 428bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 429bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 430bf215546Sopenharmony_ci dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F; 431bf215546Sopenharmony_ci } 432bf215546Sopenharmony_ci } 433bf215546Sopenharmony_ci 434bf215546Sopenharmony_ci else if (datatype == GL_HALF_FLOAT_ARB && comps == 4) { 435bf215546Sopenharmony_ci GLuint i, j, k, comp; 436bf215546Sopenharmony_ci const GLhalfARB(*rowA)[4] = (const GLhalfARB(*)[4]) srcRowA; 437bf215546Sopenharmony_ci const GLhalfARB(*rowB)[4] = (const GLhalfARB(*)[4]) srcRowB; 438bf215546Sopenharmony_ci GLhalfARB(*dst)[4] = (GLhalfARB(*)[4]) dstRow; 439bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 440bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 441bf215546Sopenharmony_ci for (comp = 0; comp < 4; comp++) { 442bf215546Sopenharmony_ci GLfloat aj, ak, bj, bk; 443bf215546Sopenharmony_ci aj = _mesa_half_to_float(rowA[j][comp]); 444bf215546Sopenharmony_ci ak = _mesa_half_to_float(rowA[k][comp]); 445bf215546Sopenharmony_ci bj = _mesa_half_to_float(rowB[j][comp]); 446bf215546Sopenharmony_ci bk = _mesa_half_to_float(rowB[k][comp]); 447bf215546Sopenharmony_ci dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 448bf215546Sopenharmony_ci } 449bf215546Sopenharmony_ci } 450bf215546Sopenharmony_ci } 451bf215546Sopenharmony_ci else if (datatype == GL_HALF_FLOAT_ARB && comps == 3) { 452bf215546Sopenharmony_ci GLuint i, j, k, comp; 453bf215546Sopenharmony_ci const GLhalfARB(*rowA)[3] = (const GLhalfARB(*)[3]) srcRowA; 454bf215546Sopenharmony_ci const GLhalfARB(*rowB)[3] = (const GLhalfARB(*)[3]) srcRowB; 455bf215546Sopenharmony_ci GLhalfARB(*dst)[3] = (GLhalfARB(*)[3]) dstRow; 456bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 457bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 458bf215546Sopenharmony_ci for (comp = 0; comp < 3; comp++) { 459bf215546Sopenharmony_ci GLfloat aj, ak, bj, bk; 460bf215546Sopenharmony_ci aj = _mesa_half_to_float(rowA[j][comp]); 461bf215546Sopenharmony_ci ak = _mesa_half_to_float(rowA[k][comp]); 462bf215546Sopenharmony_ci bj = _mesa_half_to_float(rowB[j][comp]); 463bf215546Sopenharmony_ci bk = _mesa_half_to_float(rowB[k][comp]); 464bf215546Sopenharmony_ci dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 465bf215546Sopenharmony_ci } 466bf215546Sopenharmony_ci } 467bf215546Sopenharmony_ci } 468bf215546Sopenharmony_ci else if (datatype == GL_HALF_FLOAT_ARB && comps == 2) { 469bf215546Sopenharmony_ci GLuint i, j, k, comp; 470bf215546Sopenharmony_ci const GLhalfARB(*rowA)[2] = (const GLhalfARB(*)[2]) srcRowA; 471bf215546Sopenharmony_ci const GLhalfARB(*rowB)[2] = (const GLhalfARB(*)[2]) srcRowB; 472bf215546Sopenharmony_ci GLhalfARB(*dst)[2] = (GLhalfARB(*)[2]) dstRow; 473bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 474bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 475bf215546Sopenharmony_ci for (comp = 0; comp < 2; comp++) { 476bf215546Sopenharmony_ci GLfloat aj, ak, bj, bk; 477bf215546Sopenharmony_ci aj = _mesa_half_to_float(rowA[j][comp]); 478bf215546Sopenharmony_ci ak = _mesa_half_to_float(rowA[k][comp]); 479bf215546Sopenharmony_ci bj = _mesa_half_to_float(rowB[j][comp]); 480bf215546Sopenharmony_ci bk = _mesa_half_to_float(rowB[k][comp]); 481bf215546Sopenharmony_ci dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 482bf215546Sopenharmony_ci } 483bf215546Sopenharmony_ci } 484bf215546Sopenharmony_ci } 485bf215546Sopenharmony_ci else if (datatype == GL_HALF_FLOAT_ARB && comps == 1) { 486bf215546Sopenharmony_ci GLuint i, j, k; 487bf215546Sopenharmony_ci const GLhalfARB *rowA = (const GLhalfARB *) srcRowA; 488bf215546Sopenharmony_ci const GLhalfARB *rowB = (const GLhalfARB *) srcRowB; 489bf215546Sopenharmony_ci GLhalfARB *dst = (GLhalfARB *) dstRow; 490bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 491bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 492bf215546Sopenharmony_ci GLfloat aj, ak, bj, bk; 493bf215546Sopenharmony_ci aj = _mesa_half_to_float(rowA[j]); 494bf215546Sopenharmony_ci ak = _mesa_half_to_float(rowA[k]); 495bf215546Sopenharmony_ci bj = _mesa_half_to_float(rowB[j]); 496bf215546Sopenharmony_ci bk = _mesa_half_to_float(rowB[k]); 497bf215546Sopenharmony_ci dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F); 498bf215546Sopenharmony_ci } 499bf215546Sopenharmony_ci } 500bf215546Sopenharmony_ci 501bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT && comps == 1) { 502bf215546Sopenharmony_ci GLuint i, j, k; 503bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint *) srcRowA; 504bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint *) srcRowB; 505bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dstRow; 506bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 507bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 508bf215546Sopenharmony_ci dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4; 509bf215546Sopenharmony_ci } 510bf215546Sopenharmony_ci } 511bf215546Sopenharmony_ci 512bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT_5_6_5 && comps == 3) { 513bf215546Sopenharmony_ci GLuint i, j, k; 514bf215546Sopenharmony_ci const GLushort *rowA = (const GLushort *) srcRowA; 515bf215546Sopenharmony_ci const GLushort *rowB = (const GLushort *) srcRowB; 516bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dstRow; 517bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 518bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 519bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x1f; 520bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x1f; 521bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x1f; 522bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x1f; 523bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; 524bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; 525bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; 526bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; 527bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; 528bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; 529bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; 530bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; 531bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 532bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 533bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 534bf215546Sopenharmony_ci dst[i] = (blue << 11) | (green << 5) | red; 535bf215546Sopenharmony_ci } 536bf215546Sopenharmony_ci } 537bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT_4_4_4_4 && comps == 4) { 538bf215546Sopenharmony_ci GLuint i, j, k; 539bf215546Sopenharmony_ci const GLushort *rowA = (const GLushort *) srcRowA; 540bf215546Sopenharmony_ci const GLushort *rowB = (const GLushort *) srcRowB; 541bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dstRow; 542bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 543bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 544bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0xf; 545bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0xf; 546bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0xf; 547bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0xf; 548bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 549bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 550bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 551bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 552bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 8) & 0xf; 553bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 8) & 0xf; 554bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 8) & 0xf; 555bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 8) & 0xf; 556bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 12) & 0xf; 557bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 12) & 0xf; 558bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 12) & 0xf; 559bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 12) & 0xf; 560bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 561bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 562bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 563bf215546Sopenharmony_ci const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 564bf215546Sopenharmony_ci dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red; 565bf215546Sopenharmony_ci } 566bf215546Sopenharmony_ci } 567bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV && comps == 4) { 568bf215546Sopenharmony_ci GLuint i, j, k; 569bf215546Sopenharmony_ci const GLushort *rowA = (const GLushort *) srcRowA; 570bf215546Sopenharmony_ci const GLushort *rowB = (const GLushort *) srcRowB; 571bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dstRow; 572bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 573bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 574bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x1f; 575bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x1f; 576bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x1f; 577bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x1f; 578bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; 579bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; 580bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; 581bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; 582bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; 583bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; 584bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; 585bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; 586bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 15) & 0x1; 587bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 15) & 0x1; 588bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 15) & 0x1; 589bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 15) & 0x1; 590bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 591bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 592bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 593bf215546Sopenharmony_ci const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 594bf215546Sopenharmony_ci dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red; 595bf215546Sopenharmony_ci } 596bf215546Sopenharmony_ci } 597bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_SHORT_5_5_5_1 && comps == 4) { 598bf215546Sopenharmony_ci GLuint i, j, k; 599bf215546Sopenharmony_ci const GLushort *rowA = (const GLushort *) srcRowA; 600bf215546Sopenharmony_ci const GLushort *rowB = (const GLushort *) srcRowB; 601bf215546Sopenharmony_ci GLushort *dst = (GLushort *) dstRow; 602bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 603bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 604bf215546Sopenharmony_ci const GLint rowAr0 = (rowA[j] >> 11) & 0x1f; 605bf215546Sopenharmony_ci const GLint rowAr1 = (rowA[k] >> 11) & 0x1f; 606bf215546Sopenharmony_ci const GLint rowBr0 = (rowB[j] >> 11) & 0x1f; 607bf215546Sopenharmony_ci const GLint rowBr1 = (rowB[k] >> 11) & 0x1f; 608bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 6) & 0x1f; 609bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 6) & 0x1f; 610bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 6) & 0x1f; 611bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 6) & 0x1f; 612bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 1) & 0x1f; 613bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 1) & 0x1f; 614bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 1) & 0x1f; 615bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 1) & 0x1f; 616bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] & 0x1); 617bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] & 0x1); 618bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] & 0x1); 619bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] & 0x1); 620bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 621bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 622bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 623bf215546Sopenharmony_ci const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 624bf215546Sopenharmony_ci dst[i] = (red << 11) | (green << 6) | (blue << 1) | alpha; 625bf215546Sopenharmony_ci } 626bf215546Sopenharmony_ci } 627bf215546Sopenharmony_ci 628bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_BYTE_3_3_2 && comps == 3) { 629bf215546Sopenharmony_ci GLuint i, j, k; 630bf215546Sopenharmony_ci const GLubyte *rowA = (const GLubyte *) srcRowA; 631bf215546Sopenharmony_ci const GLubyte *rowB = (const GLubyte *) srcRowB; 632bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dstRow; 633bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 634bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 635bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x3; 636bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x3; 637bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x3; 638bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x3; 639bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 2) & 0x7; 640bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 2) & 0x7; 641bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 2) & 0x7; 642bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 2) & 0x7; 643bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 5) & 0x7; 644bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 5) & 0x7; 645bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 5) & 0x7; 646bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 5) & 0x7; 647bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 648bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 649bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 650bf215546Sopenharmony_ci dst[i] = (blue << 5) | (green << 2) | red; 651bf215546Sopenharmony_ci } 652bf215546Sopenharmony_ci } 653bf215546Sopenharmony_ci 654bf215546Sopenharmony_ci else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) { 655bf215546Sopenharmony_ci GLuint i, j, k; 656bf215546Sopenharmony_ci const GLubyte *rowA = (const GLubyte *) srcRowA; 657bf215546Sopenharmony_ci const GLubyte *rowB = (const GLubyte *) srcRowB; 658bf215546Sopenharmony_ci GLubyte *dst = (GLubyte *) dstRow; 659bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 660bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 661bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0xf; 662bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0xf; 663bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0xf; 664bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0xf; 665bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 666bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 667bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 668bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 669bf215546Sopenharmony_ci const GLint r = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 670bf215546Sopenharmony_ci const GLint g = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 671bf215546Sopenharmony_ci dst[i] = (g << 4) | r; 672bf215546Sopenharmony_ci } 673bf215546Sopenharmony_ci } 674bf215546Sopenharmony_ci 675bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_2_10_10_10_REV && comps == 4) { 676bf215546Sopenharmony_ci GLuint i, j, k; 677bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint *) srcRowA; 678bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint *) srcRowB; 679bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dstRow; 680bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 681bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 682bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x3ff; 683bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x3ff; 684bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x3ff; 685bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x3ff; 686bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 10) & 0x3ff; 687bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 10) & 0x3ff; 688bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 10) & 0x3ff; 689bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 10) & 0x3ff; 690bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 20) & 0x3ff; 691bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 20) & 0x3ff; 692bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 20) & 0x3ff; 693bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 20) & 0x3ff; 694bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 30) & 0x3; 695bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 30) & 0x3; 696bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 30) & 0x3; 697bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 30) & 0x3; 698bf215546Sopenharmony_ci const GLint red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2; 699bf215546Sopenharmony_ci const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2; 700bf215546Sopenharmony_ci const GLint blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2; 701bf215546Sopenharmony_ci const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2; 702bf215546Sopenharmony_ci dst[i] = (alpha << 30) | (blue << 20) | (green << 10) | red; 703bf215546Sopenharmony_ci } 704bf215546Sopenharmony_ci } 705bf215546Sopenharmony_ci 706bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) { 707bf215546Sopenharmony_ci GLuint i, j, k; 708bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint*) srcRowA; 709bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint*) srcRowB; 710bf215546Sopenharmony_ci GLuint *dst = (GLuint*)dstRow; 711bf215546Sopenharmony_ci GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3]; 712bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 713bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 714bf215546Sopenharmony_ci rgb9e5_to_float3(rowA[j], rowAj); 715bf215546Sopenharmony_ci rgb9e5_to_float3(rowB[j], rowBj); 716bf215546Sopenharmony_ci rgb9e5_to_float3(rowA[k], rowAk); 717bf215546Sopenharmony_ci rgb9e5_to_float3(rowB[k], rowBk); 718bf215546Sopenharmony_ci res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F; 719bf215546Sopenharmony_ci res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F; 720bf215546Sopenharmony_ci res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F; 721bf215546Sopenharmony_ci dst[i] = float3_to_rgb9e5(res); 722bf215546Sopenharmony_ci } 723bf215546Sopenharmony_ci } 724bf215546Sopenharmony_ci 725bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) { 726bf215546Sopenharmony_ci GLuint i, j, k; 727bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint*) srcRowA; 728bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint*) srcRowB; 729bf215546Sopenharmony_ci GLuint *dst = (GLuint*)dstRow; 730bf215546Sopenharmony_ci GLfloat res[3], rowAj[3], rowBj[3], rowAk[3], rowBk[3]; 731bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 732bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 733bf215546Sopenharmony_ci r11g11b10f_to_float3(rowA[j], rowAj); 734bf215546Sopenharmony_ci r11g11b10f_to_float3(rowB[j], rowBj); 735bf215546Sopenharmony_ci r11g11b10f_to_float3(rowA[k], rowAk); 736bf215546Sopenharmony_ci r11g11b10f_to_float3(rowB[k], rowBk); 737bf215546Sopenharmony_ci res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0]) * 0.25F; 738bf215546Sopenharmony_ci res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1]) * 0.25F; 739bf215546Sopenharmony_ci res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2]) * 0.25F; 740bf215546Sopenharmony_ci dst[i] = float3_to_r11g11b10f(res); 741bf215546Sopenharmony_ci } 742bf215546Sopenharmony_ci } 743bf215546Sopenharmony_ci 744bf215546Sopenharmony_ci else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && comps == 1) { 745bf215546Sopenharmony_ci GLuint i, j, k; 746bf215546Sopenharmony_ci const GLfloat *rowA = (const GLfloat *) srcRowA; 747bf215546Sopenharmony_ci const GLfloat *rowB = (const GLfloat *) srcRowB; 748bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dstRow; 749bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 750bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 751bf215546Sopenharmony_ci dst[i*2] = (rowA[j*2] + rowA[k*2] + rowB[j*2] + rowB[k*2]) * 0.25F; 752bf215546Sopenharmony_ci } 753bf215546Sopenharmony_ci } 754bf215546Sopenharmony_ci 755bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_24_8_MESA && comps == 2) { 756bf215546Sopenharmony_ci GLuint i, j, k; 757bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint *) srcRowA; 758bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint *) srcRowB; 759bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dstRow; 760bf215546Sopenharmony_ci /* note: averaging stencil values seems weird, but what else? */ 761bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 762bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 763bf215546Sopenharmony_ci GLuint z = (((rowA[j] >> 8) + (rowA[k] >> 8) + 764bf215546Sopenharmony_ci (rowB[j] >> 8) + (rowB[k] >> 8)) / 4) << 8; 765bf215546Sopenharmony_ci GLuint s = ((rowA[j] & 0xff) + (rowA[k] & 0xff) + 766bf215546Sopenharmony_ci (rowB[j] & 0xff) + (rowB[k] & 0xff)) / 4; 767bf215546Sopenharmony_ci dst[i] = z | s; 768bf215546Sopenharmony_ci } 769bf215546Sopenharmony_ci } 770bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_8_24_REV_MESA && comps == 2) { 771bf215546Sopenharmony_ci GLuint i, j, k; 772bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint *) srcRowA; 773bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint *) srcRowB; 774bf215546Sopenharmony_ci GLuint *dst = (GLuint *) dstRow; 775bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 776bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 777bf215546Sopenharmony_ci GLuint z = ((rowA[j] & 0xffffff) + (rowA[k] & 0xffffff) + 778bf215546Sopenharmony_ci (rowB[j] & 0xffffff) + (rowB[k] & 0xffffff)) / 4; 779bf215546Sopenharmony_ci GLuint s = (((rowA[j] >> 24) + (rowA[k] >> 24) + 780bf215546Sopenharmony_ci (rowB[j] >> 24) + (rowB[k] >> 24)) / 4) << 24; 781bf215546Sopenharmony_ci dst[i] = z | s; 782bf215546Sopenharmony_ci } 783bf215546Sopenharmony_ci } 784bf215546Sopenharmony_ci 785bf215546Sopenharmony_ci else { 786bf215546Sopenharmony_ci unreachable("bad format in do_row()"); 787bf215546Sopenharmony_ci } 788bf215546Sopenharmony_ci} 789bf215546Sopenharmony_ci 790bf215546Sopenharmony_ci 791bf215546Sopenharmony_ci/** 792bf215546Sopenharmony_ci * Average together four rows of a source image to produce a single new 793bf215546Sopenharmony_ci * row in the dest image. It's legal for the two source rows to point 794bf215546Sopenharmony_ci * to the same data. The source width must be equal to either the 795bf215546Sopenharmony_ci * dest width or two times the dest width. 796bf215546Sopenharmony_ci * 797bf215546Sopenharmony_ci * \param datatype GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT, 798bf215546Sopenharmony_ci * \c GL_FLOAT, etc. 799bf215546Sopenharmony_ci * \param comps number of components per pixel (1..4) 800bf215546Sopenharmony_ci * \param srcWidth Width of a row in the source data 801bf215546Sopenharmony_ci * \param srcRowA Pointer to one of the rows of source data 802bf215546Sopenharmony_ci * \param srcRowB Pointer to one of the rows of source data 803bf215546Sopenharmony_ci * \param srcRowC Pointer to one of the rows of source data 804bf215546Sopenharmony_ci * \param srcRowD Pointer to one of the rows of source data 805bf215546Sopenharmony_ci * \param dstWidth Width of a row in the destination data 806bf215546Sopenharmony_ci * \param srcRowA Pointer to the row of destination data 807bf215546Sopenharmony_ci */ 808bf215546Sopenharmony_cistatic void 809bf215546Sopenharmony_cido_row_3D(GLenum datatype, GLuint comps, GLint srcWidth, 810bf215546Sopenharmony_ci const GLvoid *srcRowA, const GLvoid *srcRowB, 811bf215546Sopenharmony_ci const GLvoid *srcRowC, const GLvoid *srcRowD, 812bf215546Sopenharmony_ci GLint dstWidth, GLvoid *dstRow) 813bf215546Sopenharmony_ci{ 814bf215546Sopenharmony_ci const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1; 815bf215546Sopenharmony_ci const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2; 816bf215546Sopenharmony_ci GLuint i, j, k; 817bf215546Sopenharmony_ci 818bf215546Sopenharmony_ci assert(comps >= 1); 819bf215546Sopenharmony_ci assert(comps <= 4); 820bf215546Sopenharmony_ci 821bf215546Sopenharmony_ci if ((datatype == GL_UNSIGNED_BYTE) && (comps == 4)) { 822bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLubyte, 4); 823bf215546Sopenharmony_ci 824bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 825bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 826bf215546Sopenharmony_ci FILTER_3D(0); 827bf215546Sopenharmony_ci FILTER_3D(1); 828bf215546Sopenharmony_ci FILTER_3D(2); 829bf215546Sopenharmony_ci FILTER_3D(3); 830bf215546Sopenharmony_ci } 831bf215546Sopenharmony_ci } 832bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 3)) { 833bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLubyte, 3); 834bf215546Sopenharmony_ci 835bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 836bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 837bf215546Sopenharmony_ci FILTER_3D(0); 838bf215546Sopenharmony_ci FILTER_3D(1); 839bf215546Sopenharmony_ci FILTER_3D(2); 840bf215546Sopenharmony_ci } 841bf215546Sopenharmony_ci } 842bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 2)) { 843bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLubyte, 2); 844bf215546Sopenharmony_ci 845bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 846bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 847bf215546Sopenharmony_ci FILTER_3D(0); 848bf215546Sopenharmony_ci FILTER_3D(1); 849bf215546Sopenharmony_ci } 850bf215546Sopenharmony_ci } 851bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_BYTE) && (comps == 1)) { 852bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLubyte, 1); 853bf215546Sopenharmony_ci 854bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 855bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 856bf215546Sopenharmony_ci FILTER_3D(0); 857bf215546Sopenharmony_ci } 858bf215546Sopenharmony_ci } 859bf215546Sopenharmony_ci else if ((datatype == GL_BYTE) && (comps == 4)) { 860bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLbyte, 4); 861bf215546Sopenharmony_ci 862bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 863bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 864bf215546Sopenharmony_ci FILTER_3D_SIGNED(0); 865bf215546Sopenharmony_ci FILTER_3D_SIGNED(1); 866bf215546Sopenharmony_ci FILTER_3D_SIGNED(2); 867bf215546Sopenharmony_ci FILTER_3D_SIGNED(3); 868bf215546Sopenharmony_ci } 869bf215546Sopenharmony_ci } 870bf215546Sopenharmony_ci else if ((datatype == GL_BYTE) && (comps == 3)) { 871bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLbyte, 3); 872bf215546Sopenharmony_ci 873bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 874bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 875bf215546Sopenharmony_ci FILTER_3D_SIGNED(0); 876bf215546Sopenharmony_ci FILTER_3D_SIGNED(1); 877bf215546Sopenharmony_ci FILTER_3D_SIGNED(2); 878bf215546Sopenharmony_ci } 879bf215546Sopenharmony_ci } 880bf215546Sopenharmony_ci else if ((datatype == GL_BYTE) && (comps == 2)) { 881bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLbyte, 2); 882bf215546Sopenharmony_ci 883bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 884bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 885bf215546Sopenharmony_ci FILTER_3D_SIGNED(0); 886bf215546Sopenharmony_ci FILTER_3D_SIGNED(1); 887bf215546Sopenharmony_ci } 888bf215546Sopenharmony_ci } 889bf215546Sopenharmony_ci else if ((datatype == GL_BYTE) && (comps == 1)) { 890bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLbyte, 1); 891bf215546Sopenharmony_ci 892bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 893bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 894bf215546Sopenharmony_ci FILTER_3D_SIGNED(0); 895bf215546Sopenharmony_ci } 896bf215546Sopenharmony_ci } 897bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 4)) { 898bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLushort, 4); 899bf215546Sopenharmony_ci 900bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 901bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 902bf215546Sopenharmony_ci FILTER_3D(0); 903bf215546Sopenharmony_ci FILTER_3D(1); 904bf215546Sopenharmony_ci FILTER_3D(2); 905bf215546Sopenharmony_ci FILTER_3D(3); 906bf215546Sopenharmony_ci } 907bf215546Sopenharmony_ci } 908bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 3)) { 909bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLushort, 3); 910bf215546Sopenharmony_ci 911bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 912bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 913bf215546Sopenharmony_ci FILTER_3D(0); 914bf215546Sopenharmony_ci FILTER_3D(1); 915bf215546Sopenharmony_ci FILTER_3D(2); 916bf215546Sopenharmony_ci } 917bf215546Sopenharmony_ci } 918bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 2)) { 919bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLushort, 2); 920bf215546Sopenharmony_ci 921bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 922bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 923bf215546Sopenharmony_ci FILTER_3D(0); 924bf215546Sopenharmony_ci FILTER_3D(1); 925bf215546Sopenharmony_ci } 926bf215546Sopenharmony_ci } 927bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT) && (comps == 1)) { 928bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLushort, 1); 929bf215546Sopenharmony_ci 930bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 931bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 932bf215546Sopenharmony_ci FILTER_3D(0); 933bf215546Sopenharmony_ci } 934bf215546Sopenharmony_ci } 935bf215546Sopenharmony_ci else if ((datatype == GL_SHORT) && (comps == 4)) { 936bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLshort, 4); 937bf215546Sopenharmony_ci 938bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 939bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 940bf215546Sopenharmony_ci FILTER_3D(0); 941bf215546Sopenharmony_ci FILTER_3D(1); 942bf215546Sopenharmony_ci FILTER_3D(2); 943bf215546Sopenharmony_ci FILTER_3D(3); 944bf215546Sopenharmony_ci } 945bf215546Sopenharmony_ci } 946bf215546Sopenharmony_ci else if ((datatype == GL_SHORT) && (comps == 3)) { 947bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLshort, 3); 948bf215546Sopenharmony_ci 949bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 950bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 951bf215546Sopenharmony_ci FILTER_3D(0); 952bf215546Sopenharmony_ci FILTER_3D(1); 953bf215546Sopenharmony_ci FILTER_3D(2); 954bf215546Sopenharmony_ci } 955bf215546Sopenharmony_ci } 956bf215546Sopenharmony_ci else if ((datatype == GL_SHORT) && (comps == 2)) { 957bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLshort, 2); 958bf215546Sopenharmony_ci 959bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 960bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 961bf215546Sopenharmony_ci FILTER_3D(0); 962bf215546Sopenharmony_ci FILTER_3D(1); 963bf215546Sopenharmony_ci } 964bf215546Sopenharmony_ci } 965bf215546Sopenharmony_ci else if ((datatype == GL_SHORT) && (comps == 1)) { 966bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLshort, 1); 967bf215546Sopenharmony_ci 968bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 969bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 970bf215546Sopenharmony_ci FILTER_3D(0); 971bf215546Sopenharmony_ci } 972bf215546Sopenharmony_ci } 973bf215546Sopenharmony_ci else if ((datatype == GL_FLOAT) && (comps == 4)) { 974bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLfloat, 4); 975bf215546Sopenharmony_ci 976bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 977bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 978bf215546Sopenharmony_ci FILTER_F_3D(0); 979bf215546Sopenharmony_ci FILTER_F_3D(1); 980bf215546Sopenharmony_ci FILTER_F_3D(2); 981bf215546Sopenharmony_ci FILTER_F_3D(3); 982bf215546Sopenharmony_ci } 983bf215546Sopenharmony_ci } 984bf215546Sopenharmony_ci else if ((datatype == GL_FLOAT) && (comps == 3)) { 985bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLfloat, 3); 986bf215546Sopenharmony_ci 987bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 988bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 989bf215546Sopenharmony_ci FILTER_F_3D(0); 990bf215546Sopenharmony_ci FILTER_F_3D(1); 991bf215546Sopenharmony_ci FILTER_F_3D(2); 992bf215546Sopenharmony_ci } 993bf215546Sopenharmony_ci } 994bf215546Sopenharmony_ci else if ((datatype == GL_FLOAT) && (comps == 2)) { 995bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLfloat, 2); 996bf215546Sopenharmony_ci 997bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 998bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 999bf215546Sopenharmony_ci FILTER_F_3D(0); 1000bf215546Sopenharmony_ci FILTER_F_3D(1); 1001bf215546Sopenharmony_ci } 1002bf215546Sopenharmony_ci } 1003bf215546Sopenharmony_ci else if ((datatype == GL_FLOAT) && (comps == 1)) { 1004bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLfloat, 1); 1005bf215546Sopenharmony_ci 1006bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1007bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1008bf215546Sopenharmony_ci FILTER_F_3D(0); 1009bf215546Sopenharmony_ci } 1010bf215546Sopenharmony_ci } 1011bf215546Sopenharmony_ci else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 4)) { 1012bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLhalfARB, 4); 1013bf215546Sopenharmony_ci 1014bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1015bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1016bf215546Sopenharmony_ci FILTER_HF_3D(0); 1017bf215546Sopenharmony_ci FILTER_HF_3D(1); 1018bf215546Sopenharmony_ci FILTER_HF_3D(2); 1019bf215546Sopenharmony_ci FILTER_HF_3D(3); 1020bf215546Sopenharmony_ci } 1021bf215546Sopenharmony_ci } 1022bf215546Sopenharmony_ci else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 3)) { 1023bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLhalfARB, 3); 1024bf215546Sopenharmony_ci 1025bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1026bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1027bf215546Sopenharmony_ci FILTER_HF_3D(0); 1028bf215546Sopenharmony_ci FILTER_HF_3D(1); 1029bf215546Sopenharmony_ci FILTER_HF_3D(2); 1030bf215546Sopenharmony_ci } 1031bf215546Sopenharmony_ci } 1032bf215546Sopenharmony_ci else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 2)) { 1033bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLhalfARB, 2); 1034bf215546Sopenharmony_ci 1035bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1036bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1037bf215546Sopenharmony_ci FILTER_HF_3D(0); 1038bf215546Sopenharmony_ci FILTER_HF_3D(1); 1039bf215546Sopenharmony_ci } 1040bf215546Sopenharmony_ci } 1041bf215546Sopenharmony_ci else if ((datatype == GL_HALF_FLOAT_ARB) && (comps == 1)) { 1042bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLhalfARB, 1); 1043bf215546Sopenharmony_ci 1044bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1045bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1046bf215546Sopenharmony_ci FILTER_HF_3D(0); 1047bf215546Sopenharmony_ci } 1048bf215546Sopenharmony_ci } 1049bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_INT) && (comps == 1)) { 1050bf215546Sopenharmony_ci const GLuint *rowA = (const GLuint *) srcRowA; 1051bf215546Sopenharmony_ci const GLuint *rowB = (const GLuint *) srcRowB; 1052bf215546Sopenharmony_ci const GLuint *rowC = (const GLuint *) srcRowC; 1053bf215546Sopenharmony_ci const GLuint *rowD = (const GLuint *) srcRowD; 1054bf215546Sopenharmony_ci GLfloat *dst = (GLfloat *) dstRow; 1055bf215546Sopenharmony_ci 1056bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1057bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1058bf215546Sopenharmony_ci const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k]) 1059bf215546Sopenharmony_ci + ((uint64_t) rowB[j] + (uint64_t) rowB[k]) 1060bf215546Sopenharmony_ci + ((uint64_t) rowC[j] + (uint64_t) rowC[k]) 1061bf215546Sopenharmony_ci + ((uint64_t) rowD[j] + (uint64_t) rowD[k])); 1062bf215546Sopenharmony_ci dst[i] = (GLfloat)((double) tmp * 0.125); 1063bf215546Sopenharmony_ci } 1064bf215546Sopenharmony_ci } 1065bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT_5_6_5) && (comps == 3)) { 1066bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLushort); 1067bf215546Sopenharmony_ci 1068bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1069bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1070bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x1f; 1071bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x1f; 1072bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x1f; 1073bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x1f; 1074bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0x1f; 1075bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0x1f; 1076bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0x1f; 1077bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0x1f; 1078bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 5) & 0x3f; 1079bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 5) & 0x3f; 1080bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 5) & 0x3f; 1081bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 5) & 0x3f; 1082bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 5) & 0x3f; 1083bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 5) & 0x3f; 1084bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 5) & 0x3f; 1085bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 5) & 0x3f; 1086bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 11) & 0x1f; 1087bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 11) & 0x1f; 1088bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 11) & 0x1f; 1089bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 11) & 0x1f; 1090bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 11) & 0x1f; 1091bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 11) & 0x1f; 1092bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 11) & 0x1f; 1093bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 11) & 0x1f; 1094bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1095bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1096bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1097bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1098bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1099bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1100bf215546Sopenharmony_ci dst[i] = (b << 11) | (g << 5) | r; 1101bf215546Sopenharmony_ci } 1102bf215546Sopenharmony_ci } 1103bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT_4_4_4_4) && (comps == 4)) { 1104bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLushort); 1105bf215546Sopenharmony_ci 1106bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1107bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1108bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0xf; 1109bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0xf; 1110bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0xf; 1111bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0xf; 1112bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0xf; 1113bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0xf; 1114bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0xf; 1115bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0xf; 1116bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 1117bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 1118bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 1119bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 1120bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 4) & 0xf; 1121bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 4) & 0xf; 1122bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 4) & 0xf; 1123bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 4) & 0xf; 1124bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 8) & 0xf; 1125bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 8) & 0xf; 1126bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 8) & 0xf; 1127bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 8) & 0xf; 1128bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 8) & 0xf; 1129bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 8) & 0xf; 1130bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 8) & 0xf; 1131bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 8) & 0xf; 1132bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 12) & 0xf; 1133bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 12) & 0xf; 1134bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 12) & 0xf; 1135bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 12) & 0xf; 1136bf215546Sopenharmony_ci const GLint rowCa0 = (rowC[j] >> 12) & 0xf; 1137bf215546Sopenharmony_ci const GLint rowCa1 = (rowC[k] >> 12) & 0xf; 1138bf215546Sopenharmony_ci const GLint rowDa0 = (rowD[j] >> 12) & 0xf; 1139bf215546Sopenharmony_ci const GLint rowDa1 = (rowD[k] >> 12) & 0xf; 1140bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1141bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1142bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1143bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1144bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1145bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1146bf215546Sopenharmony_ci const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, 1147bf215546Sopenharmony_ci rowCa0, rowCa1, rowDa0, rowDa1); 1148bf215546Sopenharmony_ci 1149bf215546Sopenharmony_ci dst[i] = (a << 12) | (b << 8) | (g << 4) | r; 1150bf215546Sopenharmony_ci } 1151bf215546Sopenharmony_ci } 1152bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT_1_5_5_5_REV) && (comps == 4)) { 1153bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLushort); 1154bf215546Sopenharmony_ci 1155bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1156bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1157bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x1f; 1158bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x1f; 1159bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x1f; 1160bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x1f; 1161bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0x1f; 1162bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0x1f; 1163bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0x1f; 1164bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0x1f; 1165bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 5) & 0x1f; 1166bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 5) & 0x1f; 1167bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 5) & 0x1f; 1168bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 5) & 0x1f; 1169bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 5) & 0x1f; 1170bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 5) & 0x1f; 1171bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 5) & 0x1f; 1172bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 5) & 0x1f; 1173bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 10) & 0x1f; 1174bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 10) & 0x1f; 1175bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 10) & 0x1f; 1176bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 10) & 0x1f; 1177bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 10) & 0x1f; 1178bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 10) & 0x1f; 1179bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 10) & 0x1f; 1180bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 10) & 0x1f; 1181bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 15) & 0x1; 1182bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 15) & 0x1; 1183bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 15) & 0x1; 1184bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 15) & 0x1; 1185bf215546Sopenharmony_ci const GLint rowCa0 = (rowC[j] >> 15) & 0x1; 1186bf215546Sopenharmony_ci const GLint rowCa1 = (rowC[k] >> 15) & 0x1; 1187bf215546Sopenharmony_ci const GLint rowDa0 = (rowD[j] >> 15) & 0x1; 1188bf215546Sopenharmony_ci const GLint rowDa1 = (rowD[k] >> 15) & 0x1; 1189bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1190bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1191bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1192bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1193bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1194bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1195bf215546Sopenharmony_ci const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, 1196bf215546Sopenharmony_ci rowCa0, rowCa1, rowDa0, rowDa1); 1197bf215546Sopenharmony_ci 1198bf215546Sopenharmony_ci dst[i] = (a << 15) | (b << 10) | (g << 5) | r; 1199bf215546Sopenharmony_ci } 1200bf215546Sopenharmony_ci } 1201bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_SHORT_5_5_5_1) && (comps == 4)) { 1202bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLushort); 1203bf215546Sopenharmony_ci 1204bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1205bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1206bf215546Sopenharmony_ci const GLint rowAr0 = (rowA[j] >> 11) & 0x1f; 1207bf215546Sopenharmony_ci const GLint rowAr1 = (rowA[k] >> 11) & 0x1f; 1208bf215546Sopenharmony_ci const GLint rowBr0 = (rowB[j] >> 11) & 0x1f; 1209bf215546Sopenharmony_ci const GLint rowBr1 = (rowB[k] >> 11) & 0x1f; 1210bf215546Sopenharmony_ci const GLint rowCr0 = (rowC[j] >> 11) & 0x1f; 1211bf215546Sopenharmony_ci const GLint rowCr1 = (rowC[k] >> 11) & 0x1f; 1212bf215546Sopenharmony_ci const GLint rowDr0 = (rowD[j] >> 11) & 0x1f; 1213bf215546Sopenharmony_ci const GLint rowDr1 = (rowD[k] >> 11) & 0x1f; 1214bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 6) & 0x1f; 1215bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 6) & 0x1f; 1216bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 6) & 0x1f; 1217bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 6) & 0x1f; 1218bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 6) & 0x1f; 1219bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 6) & 0x1f; 1220bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 6) & 0x1f; 1221bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 6) & 0x1f; 1222bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 1) & 0x1f; 1223bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 1) & 0x1f; 1224bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 1) & 0x1f; 1225bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 1) & 0x1f; 1226bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 1) & 0x1f; 1227bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 1) & 0x1f; 1228bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 1) & 0x1f; 1229bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 1) & 0x1f; 1230bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] & 0x1); 1231bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] & 0x1); 1232bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] & 0x1); 1233bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] & 0x1); 1234bf215546Sopenharmony_ci const GLint rowCa0 = (rowC[j] & 0x1); 1235bf215546Sopenharmony_ci const GLint rowCa1 = (rowC[k] & 0x1); 1236bf215546Sopenharmony_ci const GLint rowDa0 = (rowD[j] & 0x1); 1237bf215546Sopenharmony_ci const GLint rowDa1 = (rowD[k] & 0x1); 1238bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1239bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1240bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1241bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1242bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1243bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1244bf215546Sopenharmony_ci const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, 1245bf215546Sopenharmony_ci rowCa0, rowCa1, rowDa0, rowDa1); 1246bf215546Sopenharmony_ci 1247bf215546Sopenharmony_ci dst[i] = (r << 11) | (g << 6) | (b << 1) | a; 1248bf215546Sopenharmony_ci } 1249bf215546Sopenharmony_ci } 1250bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_BYTE_3_3_2) && (comps == 3)) { 1251bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLubyte); 1252bf215546Sopenharmony_ci 1253bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1254bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1255bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x3; 1256bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x3; 1257bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x3; 1258bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x3; 1259bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0x3; 1260bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0x3; 1261bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0x3; 1262bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0x3; 1263bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 2) & 0x7; 1264bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 2) & 0x7; 1265bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 2) & 0x7; 1266bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 2) & 0x7; 1267bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 2) & 0x7; 1268bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 2) & 0x7; 1269bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 2) & 0x7; 1270bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 2) & 0x7; 1271bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 5) & 0x7; 1272bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 5) & 0x7; 1273bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 5) & 0x7; 1274bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 5) & 0x7; 1275bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 5) & 0x7; 1276bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 5) & 0x7; 1277bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 5) & 0x7; 1278bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 5) & 0x7; 1279bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1280bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1281bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1282bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1283bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1284bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1285bf215546Sopenharmony_ci dst[i] = (b << 5) | (g << 2) | r; 1286bf215546Sopenharmony_ci } 1287bf215546Sopenharmony_ci } 1288bf215546Sopenharmony_ci else if (datatype == MESA_UNSIGNED_BYTE_4_4 && comps == 2) { 1289bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLubyte); 1290bf215546Sopenharmony_ci 1291bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1292bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1293bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0xf; 1294bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0xf; 1295bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0xf; 1296bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0xf; 1297bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0xf; 1298bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0xf; 1299bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0xf; 1300bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0xf; 1301bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 4) & 0xf; 1302bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 4) & 0xf; 1303bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 4) & 0xf; 1304bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 4) & 0xf; 1305bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 4) & 0xf; 1306bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 4) & 0xf; 1307bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 4) & 0xf; 1308bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 4) & 0xf; 1309bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1310bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1311bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1312bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1313bf215546Sopenharmony_ci dst[i] = (g << 4) | r; 1314bf215546Sopenharmony_ci } 1315bf215546Sopenharmony_ci } 1316bf215546Sopenharmony_ci else if ((datatype == GL_UNSIGNED_INT_2_10_10_10_REV) && (comps == 4)) { 1317bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLuint); 1318bf215546Sopenharmony_ci 1319bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1320bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1321bf215546Sopenharmony_ci const GLint rowAr0 = rowA[j] & 0x3ff; 1322bf215546Sopenharmony_ci const GLint rowAr1 = rowA[k] & 0x3ff; 1323bf215546Sopenharmony_ci const GLint rowBr0 = rowB[j] & 0x3ff; 1324bf215546Sopenharmony_ci const GLint rowBr1 = rowB[k] & 0x3ff; 1325bf215546Sopenharmony_ci const GLint rowCr0 = rowC[j] & 0x3ff; 1326bf215546Sopenharmony_ci const GLint rowCr1 = rowC[k] & 0x3ff; 1327bf215546Sopenharmony_ci const GLint rowDr0 = rowD[j] & 0x3ff; 1328bf215546Sopenharmony_ci const GLint rowDr1 = rowD[k] & 0x3ff; 1329bf215546Sopenharmony_ci const GLint rowAg0 = (rowA[j] >> 10) & 0x3ff; 1330bf215546Sopenharmony_ci const GLint rowAg1 = (rowA[k] >> 10) & 0x3ff; 1331bf215546Sopenharmony_ci const GLint rowBg0 = (rowB[j] >> 10) & 0x3ff; 1332bf215546Sopenharmony_ci const GLint rowBg1 = (rowB[k] >> 10) & 0x3ff; 1333bf215546Sopenharmony_ci const GLint rowCg0 = (rowC[j] >> 10) & 0x3ff; 1334bf215546Sopenharmony_ci const GLint rowCg1 = (rowC[k] >> 10) & 0x3ff; 1335bf215546Sopenharmony_ci const GLint rowDg0 = (rowD[j] >> 10) & 0x3ff; 1336bf215546Sopenharmony_ci const GLint rowDg1 = (rowD[k] >> 10) & 0x3ff; 1337bf215546Sopenharmony_ci const GLint rowAb0 = (rowA[j] >> 20) & 0x3ff; 1338bf215546Sopenharmony_ci const GLint rowAb1 = (rowA[k] >> 20) & 0x3ff; 1339bf215546Sopenharmony_ci const GLint rowBb0 = (rowB[j] >> 20) & 0x3ff; 1340bf215546Sopenharmony_ci const GLint rowBb1 = (rowB[k] >> 20) & 0x3ff; 1341bf215546Sopenharmony_ci const GLint rowCb0 = (rowC[j] >> 20) & 0x3ff; 1342bf215546Sopenharmony_ci const GLint rowCb1 = (rowC[k] >> 20) & 0x3ff; 1343bf215546Sopenharmony_ci const GLint rowDb0 = (rowD[j] >> 20) & 0x3ff; 1344bf215546Sopenharmony_ci const GLint rowDb1 = (rowD[k] >> 20) & 0x3ff; 1345bf215546Sopenharmony_ci const GLint rowAa0 = (rowA[j] >> 30) & 0x3; 1346bf215546Sopenharmony_ci const GLint rowAa1 = (rowA[k] >> 30) & 0x3; 1347bf215546Sopenharmony_ci const GLint rowBa0 = (rowB[j] >> 30) & 0x3; 1348bf215546Sopenharmony_ci const GLint rowBa1 = (rowB[k] >> 30) & 0x3; 1349bf215546Sopenharmony_ci const GLint rowCa0 = (rowC[j] >> 30) & 0x3; 1350bf215546Sopenharmony_ci const GLint rowCa1 = (rowC[k] >> 30) & 0x3; 1351bf215546Sopenharmony_ci const GLint rowDa0 = (rowD[j] >> 30) & 0x3; 1352bf215546Sopenharmony_ci const GLint rowDa1 = (rowD[k] >> 30) & 0x3; 1353bf215546Sopenharmony_ci const GLint r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1, 1354bf215546Sopenharmony_ci rowCr0, rowCr1, rowDr0, rowDr1); 1355bf215546Sopenharmony_ci const GLint g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1, 1356bf215546Sopenharmony_ci rowCg0, rowCg1, rowDg0, rowDg1); 1357bf215546Sopenharmony_ci const GLint b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1, 1358bf215546Sopenharmony_ci rowCb0, rowCb1, rowDb0, rowDb1); 1359bf215546Sopenharmony_ci const GLint a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1, 1360bf215546Sopenharmony_ci rowCa0, rowCa1, rowDa0, rowDa1); 1361bf215546Sopenharmony_ci 1362bf215546Sopenharmony_ci dst[i] = (a << 30) | (b << 20) | (g << 10) | r; 1363bf215546Sopenharmony_ci } 1364bf215546Sopenharmony_ci } 1365bf215546Sopenharmony_ci 1366bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_5_9_9_9_REV && comps == 3) { 1367bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLuint); 1368bf215546Sopenharmony_ci 1369bf215546Sopenharmony_ci GLfloat res[3]; 1370bf215546Sopenharmony_ci GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3]; 1371bf215546Sopenharmony_ci GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3]; 1372bf215546Sopenharmony_ci 1373bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1374bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1375bf215546Sopenharmony_ci rgb9e5_to_float3(rowA[j], rowAj); 1376bf215546Sopenharmony_ci rgb9e5_to_float3(rowB[j], rowBj); 1377bf215546Sopenharmony_ci rgb9e5_to_float3(rowC[j], rowCj); 1378bf215546Sopenharmony_ci rgb9e5_to_float3(rowD[j], rowDj); 1379bf215546Sopenharmony_ci rgb9e5_to_float3(rowA[k], rowAk); 1380bf215546Sopenharmony_ci rgb9e5_to_float3(rowB[k], rowBk); 1381bf215546Sopenharmony_ci rgb9e5_to_float3(rowC[k], rowCk); 1382bf215546Sopenharmony_ci rgb9e5_to_float3(rowD[k], rowDk); 1383bf215546Sopenharmony_ci res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] + 1384bf215546Sopenharmony_ci rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F; 1385bf215546Sopenharmony_ci res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] + 1386bf215546Sopenharmony_ci rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F; 1387bf215546Sopenharmony_ci res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] + 1388bf215546Sopenharmony_ci rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F; 1389bf215546Sopenharmony_ci dst[i] = float3_to_rgb9e5(res); 1390bf215546Sopenharmony_ci } 1391bf215546Sopenharmony_ci } 1392bf215546Sopenharmony_ci 1393bf215546Sopenharmony_ci else if (datatype == GL_UNSIGNED_INT_10F_11F_11F_REV && comps == 3) { 1394bf215546Sopenharmony_ci DECLARE_ROW_POINTERS0(GLuint); 1395bf215546Sopenharmony_ci 1396bf215546Sopenharmony_ci GLfloat res[3]; 1397bf215546Sopenharmony_ci GLfloat rowAj[3], rowBj[3], rowCj[3], rowDj[3]; 1398bf215546Sopenharmony_ci GLfloat rowAk[3], rowBk[3], rowCk[3], rowDk[3]; 1399bf215546Sopenharmony_ci 1400bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1401bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1402bf215546Sopenharmony_ci r11g11b10f_to_float3(rowA[j], rowAj); 1403bf215546Sopenharmony_ci r11g11b10f_to_float3(rowB[j], rowBj); 1404bf215546Sopenharmony_ci r11g11b10f_to_float3(rowC[j], rowCj); 1405bf215546Sopenharmony_ci r11g11b10f_to_float3(rowD[j], rowDj); 1406bf215546Sopenharmony_ci r11g11b10f_to_float3(rowA[k], rowAk); 1407bf215546Sopenharmony_ci r11g11b10f_to_float3(rowB[k], rowBk); 1408bf215546Sopenharmony_ci r11g11b10f_to_float3(rowC[k], rowCk); 1409bf215546Sopenharmony_ci r11g11b10f_to_float3(rowD[k], rowDk); 1410bf215546Sopenharmony_ci res[0] = (rowAj[0] + rowAk[0] + rowBj[0] + rowBk[0] + 1411bf215546Sopenharmony_ci rowCj[0] + rowCk[0] + rowDj[0] + rowDk[0]) * 0.125F; 1412bf215546Sopenharmony_ci res[1] = (rowAj[1] + rowAk[1] + rowBj[1] + rowBk[1] + 1413bf215546Sopenharmony_ci rowCj[1] + rowCk[1] + rowDj[1] + rowDk[1]) * 0.125F; 1414bf215546Sopenharmony_ci res[2] = (rowAj[2] + rowAk[2] + rowBj[2] + rowBk[2] + 1415bf215546Sopenharmony_ci rowCj[2] + rowCk[2] + rowDj[2] + rowDk[2]) * 0.125F; 1416bf215546Sopenharmony_ci dst[i] = float3_to_r11g11b10f(res); 1417bf215546Sopenharmony_ci } 1418bf215546Sopenharmony_ci } 1419bf215546Sopenharmony_ci 1420bf215546Sopenharmony_ci else if (datatype == GL_FLOAT_32_UNSIGNED_INT_24_8_REV && comps == 1) { 1421bf215546Sopenharmony_ci DECLARE_ROW_POINTERS(GLfloat, 2); 1422bf215546Sopenharmony_ci 1423bf215546Sopenharmony_ci for (i = j = 0, k = k0; i < (GLuint) dstWidth; 1424bf215546Sopenharmony_ci i++, j += colStride, k += colStride) { 1425bf215546Sopenharmony_ci FILTER_F_3D(0); 1426bf215546Sopenharmony_ci } 1427bf215546Sopenharmony_ci } 1428bf215546Sopenharmony_ci 1429bf215546Sopenharmony_ci else { 1430bf215546Sopenharmony_ci unreachable("bad format in do_row()"); 1431bf215546Sopenharmony_ci } 1432bf215546Sopenharmony_ci} 1433bf215546Sopenharmony_ci 1434bf215546Sopenharmony_ci 1435bf215546Sopenharmony_ci/* 1436bf215546Sopenharmony_ci * These functions generate a 1/2-size mipmap image from a source image. 1437bf215546Sopenharmony_ci * Texture borders are handled by copying or averaging the source image's 1438bf215546Sopenharmony_ci * border texels, depending on the scale-down factor. 1439bf215546Sopenharmony_ci */ 1440bf215546Sopenharmony_ci 1441bf215546Sopenharmony_cistatic void 1442bf215546Sopenharmony_cimake_1d_mipmap(GLenum datatype, GLuint comps, GLint border, 1443bf215546Sopenharmony_ci GLint srcWidth, const GLubyte *srcPtr, 1444bf215546Sopenharmony_ci GLint dstWidth, GLubyte *dstPtr) 1445bf215546Sopenharmony_ci{ 1446bf215546Sopenharmony_ci const GLint bpt = bytes_per_pixel(datatype, comps); 1447bf215546Sopenharmony_ci const GLubyte *src; 1448bf215546Sopenharmony_ci GLubyte *dst; 1449bf215546Sopenharmony_ci 1450bf215546Sopenharmony_ci /* skip the border pixel, if any */ 1451bf215546Sopenharmony_ci src = srcPtr + border * bpt; 1452bf215546Sopenharmony_ci dst = dstPtr + border * bpt; 1453bf215546Sopenharmony_ci 1454bf215546Sopenharmony_ci /* we just duplicate the input row, kind of hack, saves code */ 1455bf215546Sopenharmony_ci do_row(datatype, comps, srcWidth - 2 * border, src, src, 1456bf215546Sopenharmony_ci dstWidth - 2 * border, dst); 1457bf215546Sopenharmony_ci 1458bf215546Sopenharmony_ci if (border) { 1459bf215546Sopenharmony_ci /* copy left-most pixel from source */ 1460bf215546Sopenharmony_ci assert(dstPtr); 1461bf215546Sopenharmony_ci assert(srcPtr); 1462bf215546Sopenharmony_ci memcpy(dstPtr, srcPtr, bpt); 1463bf215546Sopenharmony_ci /* copy right-most pixel from source */ 1464bf215546Sopenharmony_ci memcpy(dstPtr + (dstWidth - 1) * bpt, 1465bf215546Sopenharmony_ci srcPtr + (srcWidth - 1) * bpt, 1466bf215546Sopenharmony_ci bpt); 1467bf215546Sopenharmony_ci } 1468bf215546Sopenharmony_ci} 1469bf215546Sopenharmony_ci 1470bf215546Sopenharmony_ci 1471bf215546Sopenharmony_cistatic void 1472bf215546Sopenharmony_cimake_2d_mipmap(GLenum datatype, GLuint comps, GLint border, 1473bf215546Sopenharmony_ci GLint srcWidth, GLint srcHeight, 1474bf215546Sopenharmony_ci const GLubyte *srcPtr, GLint srcRowStride, 1475bf215546Sopenharmony_ci GLint dstWidth, GLint dstHeight, 1476bf215546Sopenharmony_ci GLubyte *dstPtr, GLint dstRowStride) 1477bf215546Sopenharmony_ci{ 1478bf215546Sopenharmony_ci const GLint bpt = bytes_per_pixel(datatype, comps); 1479bf215546Sopenharmony_ci const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 1480bf215546Sopenharmony_ci const GLint dstWidthNB = dstWidth - 2 * border; 1481bf215546Sopenharmony_ci const GLint dstHeightNB = dstHeight - 2 * border; 1482bf215546Sopenharmony_ci const GLubyte *srcA, *srcB; 1483bf215546Sopenharmony_ci GLubyte *dst; 1484bf215546Sopenharmony_ci GLint row, srcRowStep; 1485bf215546Sopenharmony_ci 1486bf215546Sopenharmony_ci /* Compute src and dst pointers, skipping any border */ 1487bf215546Sopenharmony_ci srcA = srcPtr + border * ((srcWidth + 1) * bpt); 1488bf215546Sopenharmony_ci if (srcHeight > 1 && srcHeight > dstHeight) { 1489bf215546Sopenharmony_ci /* sample from two source rows */ 1490bf215546Sopenharmony_ci srcB = srcA + srcRowStride; 1491bf215546Sopenharmony_ci srcRowStep = 2; 1492bf215546Sopenharmony_ci } 1493bf215546Sopenharmony_ci else { 1494bf215546Sopenharmony_ci /* sample from one source row */ 1495bf215546Sopenharmony_ci srcB = srcA; 1496bf215546Sopenharmony_ci srcRowStep = 1; 1497bf215546Sopenharmony_ci } 1498bf215546Sopenharmony_ci 1499bf215546Sopenharmony_ci dst = dstPtr + border * ((dstWidth + 1) * bpt); 1500bf215546Sopenharmony_ci 1501bf215546Sopenharmony_ci for (row = 0; row < dstHeightNB; row++) { 1502bf215546Sopenharmony_ci do_row(datatype, comps, srcWidthNB, srcA, srcB, 1503bf215546Sopenharmony_ci dstWidthNB, dst); 1504bf215546Sopenharmony_ci srcA += srcRowStep * srcRowStride; 1505bf215546Sopenharmony_ci srcB += srcRowStep * srcRowStride; 1506bf215546Sopenharmony_ci dst += dstRowStride; 1507bf215546Sopenharmony_ci } 1508bf215546Sopenharmony_ci 1509bf215546Sopenharmony_ci /* This is ugly but probably won't be used much */ 1510bf215546Sopenharmony_ci if (border > 0) { 1511bf215546Sopenharmony_ci /* fill in dest border */ 1512bf215546Sopenharmony_ci /* lower-left border pixel */ 1513bf215546Sopenharmony_ci assert(dstPtr); 1514bf215546Sopenharmony_ci assert(srcPtr); 1515bf215546Sopenharmony_ci memcpy(dstPtr, srcPtr, bpt); 1516bf215546Sopenharmony_ci /* lower-right border pixel */ 1517bf215546Sopenharmony_ci memcpy(dstPtr + (dstWidth - 1) * bpt, 1518bf215546Sopenharmony_ci srcPtr + (srcWidth - 1) * bpt, bpt); 1519bf215546Sopenharmony_ci /* upper-left border pixel */ 1520bf215546Sopenharmony_ci memcpy(dstPtr + dstWidth * (dstHeight - 1) * bpt, 1521bf215546Sopenharmony_ci srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt); 1522bf215546Sopenharmony_ci /* upper-right border pixel */ 1523bf215546Sopenharmony_ci memcpy(dstPtr + (dstWidth * dstHeight - 1) * bpt, 1524bf215546Sopenharmony_ci srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt); 1525bf215546Sopenharmony_ci /* lower border */ 1526bf215546Sopenharmony_ci do_row(datatype, comps, srcWidthNB, 1527bf215546Sopenharmony_ci srcPtr + bpt, 1528bf215546Sopenharmony_ci srcPtr + bpt, 1529bf215546Sopenharmony_ci dstWidthNB, dstPtr + bpt); 1530bf215546Sopenharmony_ci /* upper border */ 1531bf215546Sopenharmony_ci do_row(datatype, comps, srcWidthNB, 1532bf215546Sopenharmony_ci srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 1533bf215546Sopenharmony_ci srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt, 1534bf215546Sopenharmony_ci dstWidthNB, 1535bf215546Sopenharmony_ci dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt); 1536bf215546Sopenharmony_ci /* left and right borders */ 1537bf215546Sopenharmony_ci if (srcHeight == dstHeight) { 1538bf215546Sopenharmony_ci /* copy border pixel from src to dst */ 1539bf215546Sopenharmony_ci for (row = 1; row < srcHeight; row++) { 1540bf215546Sopenharmony_ci memcpy(dstPtr + dstWidth * row * bpt, 1541bf215546Sopenharmony_ci srcPtr + srcWidth * row * bpt, bpt); 1542bf215546Sopenharmony_ci memcpy(dstPtr + (dstWidth * row + dstWidth - 1) * bpt, 1543bf215546Sopenharmony_ci srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt); 1544bf215546Sopenharmony_ci } 1545bf215546Sopenharmony_ci } 1546bf215546Sopenharmony_ci else { 1547bf215546Sopenharmony_ci /* average two src pixels each dest pixel */ 1548bf215546Sopenharmony_ci for (row = 0; row < dstHeightNB; row += 2) { 1549bf215546Sopenharmony_ci do_row(datatype, comps, 1, 1550bf215546Sopenharmony_ci srcPtr + (srcWidth * (row * 2 + 1)) * bpt, 1551bf215546Sopenharmony_ci srcPtr + (srcWidth * (row * 2 + 2)) * bpt, 1552bf215546Sopenharmony_ci 1, dstPtr + (dstWidth * row + 1) * bpt); 1553bf215546Sopenharmony_ci do_row(datatype, comps, 1, 1554bf215546Sopenharmony_ci srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt, 1555bf215546Sopenharmony_ci srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt, 1556bf215546Sopenharmony_ci 1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt); 1557bf215546Sopenharmony_ci } 1558bf215546Sopenharmony_ci } 1559bf215546Sopenharmony_ci } 1560bf215546Sopenharmony_ci} 1561bf215546Sopenharmony_ci 1562bf215546Sopenharmony_ci 1563bf215546Sopenharmony_cistatic void 1564bf215546Sopenharmony_cimake_3d_mipmap(GLenum datatype, GLuint comps, GLint border, 1565bf215546Sopenharmony_ci GLint srcWidth, GLint srcHeight, GLint srcDepth, 1566bf215546Sopenharmony_ci const GLubyte **srcPtr, GLint srcRowStride, 1567bf215546Sopenharmony_ci GLint dstWidth, GLint dstHeight, GLint dstDepth, 1568bf215546Sopenharmony_ci GLubyte **dstPtr, GLint dstRowStride) 1569bf215546Sopenharmony_ci{ 1570bf215546Sopenharmony_ci const GLint bpt = bytes_per_pixel(datatype, comps); 1571bf215546Sopenharmony_ci const GLint srcWidthNB = srcWidth - 2 * border; /* sizes w/out border */ 1572bf215546Sopenharmony_ci const GLint srcDepthNB = srcDepth - 2 * border; 1573bf215546Sopenharmony_ci const GLint dstWidthNB = dstWidth - 2 * border; 1574bf215546Sopenharmony_ci const GLint dstHeightNB = dstHeight - 2 * border; 1575bf215546Sopenharmony_ci const GLint dstDepthNB = dstDepth - 2 * border; 1576bf215546Sopenharmony_ci GLint img, row; 1577bf215546Sopenharmony_ci GLint bytesPerSrcImage, bytesPerDstImage; 1578bf215546Sopenharmony_ci GLint srcImageOffset, srcRowOffset; 1579bf215546Sopenharmony_ci 1580bf215546Sopenharmony_ci (void) srcDepthNB; /* silence warnings */ 1581bf215546Sopenharmony_ci 1582bf215546Sopenharmony_ci bytesPerSrcImage = srcRowStride * srcHeight * bpt; 1583bf215546Sopenharmony_ci bytesPerDstImage = dstRowStride * dstHeight * bpt; 1584bf215546Sopenharmony_ci 1585bf215546Sopenharmony_ci /* Offset between adjacent src images to be averaged together */ 1586bf215546Sopenharmony_ci srcImageOffset = (srcDepth == dstDepth) ? 0 : 1; 1587bf215546Sopenharmony_ci 1588bf215546Sopenharmony_ci /* Offset between adjacent src rows to be averaged together */ 1589bf215546Sopenharmony_ci srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride; 1590bf215546Sopenharmony_ci 1591bf215546Sopenharmony_ci /* 1592bf215546Sopenharmony_ci * Need to average together up to 8 src pixels for each dest pixel. 1593bf215546Sopenharmony_ci * Break that down into 3 operations: 1594bf215546Sopenharmony_ci * 1. take two rows from source image and average them together. 1595bf215546Sopenharmony_ci * 2. take two rows from next source image and average them together. 1596bf215546Sopenharmony_ci * 3. take the two averaged rows and average them for the final dst row. 1597bf215546Sopenharmony_ci */ 1598bf215546Sopenharmony_ci 1599bf215546Sopenharmony_ci /* 1600bf215546Sopenharmony_ci printf("mip3d %d x %d x %d -> %d x %d x %d\n", 1601bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth); 1602bf215546Sopenharmony_ci */ 1603bf215546Sopenharmony_ci 1604bf215546Sopenharmony_ci for (img = 0; img < dstDepthNB; img++) { 1605bf215546Sopenharmony_ci /* first source image pointer, skipping border */ 1606bf215546Sopenharmony_ci const GLubyte *imgSrcA = srcPtr[img * 2 + border] 1607bf215546Sopenharmony_ci + srcRowStride * border + bpt * border; 1608bf215546Sopenharmony_ci /* second source image pointer, skipping border */ 1609bf215546Sopenharmony_ci const GLubyte *imgSrcB = srcPtr[img * 2 + srcImageOffset + border] 1610bf215546Sopenharmony_ci + srcRowStride * border + bpt * border; 1611bf215546Sopenharmony_ci 1612bf215546Sopenharmony_ci /* address of the dest image, skipping border */ 1613bf215546Sopenharmony_ci GLubyte *imgDst = dstPtr[img + border] 1614bf215546Sopenharmony_ci + dstRowStride * border + bpt * border; 1615bf215546Sopenharmony_ci 1616bf215546Sopenharmony_ci /* setup the four source row pointers and the dest row pointer */ 1617bf215546Sopenharmony_ci const GLubyte *srcImgARowA = imgSrcA; 1618bf215546Sopenharmony_ci const GLubyte *srcImgARowB = imgSrcA + srcRowOffset; 1619bf215546Sopenharmony_ci const GLubyte *srcImgBRowA = imgSrcB; 1620bf215546Sopenharmony_ci const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset; 1621bf215546Sopenharmony_ci GLubyte *dstImgRow = imgDst; 1622bf215546Sopenharmony_ci 1623bf215546Sopenharmony_ci for (row = 0; row < dstHeightNB; row++) { 1624bf215546Sopenharmony_ci do_row_3D(datatype, comps, srcWidthNB, 1625bf215546Sopenharmony_ci srcImgARowA, srcImgARowB, 1626bf215546Sopenharmony_ci srcImgBRowA, srcImgBRowB, 1627bf215546Sopenharmony_ci dstWidthNB, dstImgRow); 1628bf215546Sopenharmony_ci 1629bf215546Sopenharmony_ci /* advance to next rows */ 1630bf215546Sopenharmony_ci srcImgARowA += srcRowStride + srcRowOffset; 1631bf215546Sopenharmony_ci srcImgARowB += srcRowStride + srcRowOffset; 1632bf215546Sopenharmony_ci srcImgBRowA += srcRowStride + srcRowOffset; 1633bf215546Sopenharmony_ci srcImgBRowB += srcRowStride + srcRowOffset; 1634bf215546Sopenharmony_ci dstImgRow += dstRowStride; 1635bf215546Sopenharmony_ci } 1636bf215546Sopenharmony_ci } 1637bf215546Sopenharmony_ci 1638bf215546Sopenharmony_ci 1639bf215546Sopenharmony_ci /* Luckily we can leverage the make_2d_mipmap() function here! */ 1640bf215546Sopenharmony_ci if (border > 0) { 1641bf215546Sopenharmony_ci /* do front border image */ 1642bf215546Sopenharmony_ci make_2d_mipmap(datatype, comps, 1, 1643bf215546Sopenharmony_ci srcWidth, srcHeight, srcPtr[0], srcRowStride, 1644bf215546Sopenharmony_ci dstWidth, dstHeight, dstPtr[0], dstRowStride); 1645bf215546Sopenharmony_ci /* do back border image */ 1646bf215546Sopenharmony_ci make_2d_mipmap(datatype, comps, 1, 1647bf215546Sopenharmony_ci srcWidth, srcHeight, srcPtr[srcDepth - 1], srcRowStride, 1648bf215546Sopenharmony_ci dstWidth, dstHeight, dstPtr[dstDepth - 1], dstRowStride); 1649bf215546Sopenharmony_ci 1650bf215546Sopenharmony_ci /* do four remaining border edges that span the image slices */ 1651bf215546Sopenharmony_ci if (srcDepth == dstDepth) { 1652bf215546Sopenharmony_ci /* just copy border pixels from src to dst */ 1653bf215546Sopenharmony_ci for (img = 0; img < dstDepthNB; img++) { 1654bf215546Sopenharmony_ci const GLubyte *src; 1655bf215546Sopenharmony_ci GLubyte *dst; 1656bf215546Sopenharmony_ci 1657bf215546Sopenharmony_ci /* do border along [img][row=0][col=0] */ 1658bf215546Sopenharmony_ci src = srcPtr[img * 2]; 1659bf215546Sopenharmony_ci dst = dstPtr[img]; 1660bf215546Sopenharmony_ci memcpy(dst, src, bpt); 1661bf215546Sopenharmony_ci 1662bf215546Sopenharmony_ci /* do border along [img][row=dstHeight-1][col=0] */ 1663bf215546Sopenharmony_ci src = srcPtr[img * 2] + (srcHeight - 1) * srcRowStride; 1664bf215546Sopenharmony_ci dst = dstPtr[img] + (dstHeight - 1) * dstRowStride; 1665bf215546Sopenharmony_ci memcpy(dst, src, bpt); 1666bf215546Sopenharmony_ci 1667bf215546Sopenharmony_ci /* do border along [img][row=0][col=dstWidth-1] */ 1668bf215546Sopenharmony_ci src = srcPtr[img * 2] + (srcWidth - 1) * bpt; 1669bf215546Sopenharmony_ci dst = dstPtr[img] + (dstWidth - 1) * bpt; 1670bf215546Sopenharmony_ci memcpy(dst, src, bpt); 1671bf215546Sopenharmony_ci 1672bf215546Sopenharmony_ci /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 1673bf215546Sopenharmony_ci src = srcPtr[img * 2] + (bytesPerSrcImage - bpt); 1674bf215546Sopenharmony_ci dst = dstPtr[img] + (bytesPerDstImage - bpt); 1675bf215546Sopenharmony_ci memcpy(dst, src, bpt); 1676bf215546Sopenharmony_ci } 1677bf215546Sopenharmony_ci } 1678bf215546Sopenharmony_ci else { 1679bf215546Sopenharmony_ci /* average border pixels from adjacent src image pairs */ 1680bf215546Sopenharmony_ci assert(srcDepthNB == 2 * dstDepthNB); 1681bf215546Sopenharmony_ci for (img = 0; img < dstDepthNB; img++) { 1682bf215546Sopenharmony_ci const GLubyte *srcA, *srcB; 1683bf215546Sopenharmony_ci GLubyte *dst; 1684bf215546Sopenharmony_ci 1685bf215546Sopenharmony_ci /* do border along [img][row=0][col=0] */ 1686bf215546Sopenharmony_ci srcA = srcPtr[img * 2 + 0]; 1687bf215546Sopenharmony_ci srcB = srcPtr[img * 2 + srcImageOffset]; 1688bf215546Sopenharmony_ci dst = dstPtr[img]; 1689bf215546Sopenharmony_ci do_row(datatype, comps, 1, srcA, srcB, 1, dst); 1690bf215546Sopenharmony_ci 1691bf215546Sopenharmony_ci /* do border along [img][row=dstHeight-1][col=0] */ 1692bf215546Sopenharmony_ci srcA = srcPtr[img * 2 + 0] 1693bf215546Sopenharmony_ci + (srcHeight - 1) * srcRowStride; 1694bf215546Sopenharmony_ci srcB = srcPtr[img * 2 + srcImageOffset] 1695bf215546Sopenharmony_ci + (srcHeight - 1) * srcRowStride; 1696bf215546Sopenharmony_ci dst = dstPtr[img] + (dstHeight - 1) * dstRowStride; 1697bf215546Sopenharmony_ci do_row(datatype, comps, 1, srcA, srcB, 1, dst); 1698bf215546Sopenharmony_ci 1699bf215546Sopenharmony_ci /* do border along [img][row=0][col=dstWidth-1] */ 1700bf215546Sopenharmony_ci srcA = srcPtr[img * 2 + 0] + (srcWidth - 1) * bpt; 1701bf215546Sopenharmony_ci srcB = srcPtr[img * 2 + srcImageOffset] + (srcWidth - 1) * bpt; 1702bf215546Sopenharmony_ci dst = dstPtr[img] + (dstWidth - 1) * bpt; 1703bf215546Sopenharmony_ci do_row(datatype, comps, 1, srcA, srcB, 1, dst); 1704bf215546Sopenharmony_ci 1705bf215546Sopenharmony_ci /* do border along [img][row=dstHeight-1][col=dstWidth-1] */ 1706bf215546Sopenharmony_ci srcA = srcPtr[img * 2 + 0] + (bytesPerSrcImage - bpt); 1707bf215546Sopenharmony_ci srcB = srcPtr[img * 2 + srcImageOffset] + (bytesPerSrcImage - bpt); 1708bf215546Sopenharmony_ci dst = dstPtr[img] + (bytesPerDstImage - bpt); 1709bf215546Sopenharmony_ci do_row(datatype, comps, 1, srcA, srcB, 1, dst); 1710bf215546Sopenharmony_ci } 1711bf215546Sopenharmony_ci } 1712bf215546Sopenharmony_ci } 1713bf215546Sopenharmony_ci} 1714bf215546Sopenharmony_ci 1715bf215546Sopenharmony_ci 1716bf215546Sopenharmony_ci/** 1717bf215546Sopenharmony_ci * Down-sample a texture image to produce the next lower mipmap level. 1718bf215546Sopenharmony_ci * \param comps components per texel (1, 2, 3 or 4) 1719bf215546Sopenharmony_ci * \param srcData array[slice] of pointers to source image slices 1720bf215546Sopenharmony_ci * \param dstData array[slice] of pointers to dest image slices 1721bf215546Sopenharmony_ci * \param srcRowStride stride between source rows, in bytes 1722bf215546Sopenharmony_ci * \param dstRowStride stride between destination rows, in bytes 1723bf215546Sopenharmony_ci */ 1724bf215546Sopenharmony_cistatic void 1725bf215546Sopenharmony_ci_mesa_generate_mipmap_level(GLenum target, 1726bf215546Sopenharmony_ci GLenum datatype, GLuint comps, 1727bf215546Sopenharmony_ci GLint border, 1728bf215546Sopenharmony_ci GLint srcWidth, GLint srcHeight, GLint srcDepth, 1729bf215546Sopenharmony_ci const GLubyte **srcData, 1730bf215546Sopenharmony_ci GLint srcRowStride, 1731bf215546Sopenharmony_ci GLint dstWidth, GLint dstHeight, GLint dstDepth, 1732bf215546Sopenharmony_ci GLubyte **dstData, 1733bf215546Sopenharmony_ci GLint dstRowStride) 1734bf215546Sopenharmony_ci{ 1735bf215546Sopenharmony_ci int i; 1736bf215546Sopenharmony_ci 1737bf215546Sopenharmony_ci switch (target) { 1738bf215546Sopenharmony_ci case GL_TEXTURE_1D: 1739bf215546Sopenharmony_ci make_1d_mipmap(datatype, comps, border, 1740bf215546Sopenharmony_ci srcWidth, srcData[0], 1741bf215546Sopenharmony_ci dstWidth, dstData[0]); 1742bf215546Sopenharmony_ci break; 1743bf215546Sopenharmony_ci case GL_TEXTURE_2D: 1744bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_X: 1745bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: 1746bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: 1747bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: 1748bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: 1749bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: 1750bf215546Sopenharmony_ci make_2d_mipmap(datatype, comps, border, 1751bf215546Sopenharmony_ci srcWidth, srcHeight, srcData[0], srcRowStride, 1752bf215546Sopenharmony_ci dstWidth, dstHeight, dstData[0], dstRowStride); 1753bf215546Sopenharmony_ci break; 1754bf215546Sopenharmony_ci case GL_TEXTURE_3D: 1755bf215546Sopenharmony_ci make_3d_mipmap(datatype, comps, border, 1756bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 1757bf215546Sopenharmony_ci srcData, srcRowStride, 1758bf215546Sopenharmony_ci dstWidth, dstHeight, dstDepth, 1759bf215546Sopenharmony_ci dstData, dstRowStride); 1760bf215546Sopenharmony_ci break; 1761bf215546Sopenharmony_ci case GL_TEXTURE_1D_ARRAY_EXT: 1762bf215546Sopenharmony_ci assert(srcHeight == 1); 1763bf215546Sopenharmony_ci assert(dstHeight == 1); 1764bf215546Sopenharmony_ci for (i = 0; i < dstDepth; i++) { 1765bf215546Sopenharmony_ci make_1d_mipmap(datatype, comps, border, 1766bf215546Sopenharmony_ci srcWidth, srcData[i], 1767bf215546Sopenharmony_ci dstWidth, dstData[i]); 1768bf215546Sopenharmony_ci } 1769bf215546Sopenharmony_ci break; 1770bf215546Sopenharmony_ci case GL_TEXTURE_2D_ARRAY_EXT: 1771bf215546Sopenharmony_ci case GL_TEXTURE_CUBE_MAP_ARRAY: 1772bf215546Sopenharmony_ci for (i = 0; i < dstDepth; i++) { 1773bf215546Sopenharmony_ci make_2d_mipmap(datatype, comps, border, 1774bf215546Sopenharmony_ci srcWidth, srcHeight, srcData[i], srcRowStride, 1775bf215546Sopenharmony_ci dstWidth, dstHeight, dstData[i], dstRowStride); 1776bf215546Sopenharmony_ci } 1777bf215546Sopenharmony_ci break; 1778bf215546Sopenharmony_ci case GL_TEXTURE_RECTANGLE_NV: 1779bf215546Sopenharmony_ci case GL_TEXTURE_EXTERNAL_OES: 1780bf215546Sopenharmony_ci /* no mipmaps, do nothing */ 1781bf215546Sopenharmony_ci break; 1782bf215546Sopenharmony_ci default: 1783bf215546Sopenharmony_ci unreachable("bad tex target in _mesa_generate_mipmaps"); 1784bf215546Sopenharmony_ci } 1785bf215546Sopenharmony_ci} 1786bf215546Sopenharmony_ci 1787bf215546Sopenharmony_ci 1788bf215546Sopenharmony_ci/** 1789bf215546Sopenharmony_ci * compute next (level+1) image size 1790bf215546Sopenharmony_ci * \return GL_FALSE if no smaller size can be generated (eg. src is 1x1x1 size) 1791bf215546Sopenharmony_ci */ 1792bf215546Sopenharmony_ciGLboolean 1793bf215546Sopenharmony_ci_mesa_next_mipmap_level_size(GLenum target, GLint border, 1794bf215546Sopenharmony_ci GLint srcWidth, GLint srcHeight, GLint srcDepth, 1795bf215546Sopenharmony_ci GLint *dstWidth, GLint *dstHeight, GLint *dstDepth) 1796bf215546Sopenharmony_ci{ 1797bf215546Sopenharmony_ci if (srcWidth - 2 * border > 1) { 1798bf215546Sopenharmony_ci *dstWidth = (srcWidth - 2 * border) / 2 + 2 * border; 1799bf215546Sopenharmony_ci } 1800bf215546Sopenharmony_ci else { 1801bf215546Sopenharmony_ci *dstWidth = srcWidth; /* can't go smaller */ 1802bf215546Sopenharmony_ci } 1803bf215546Sopenharmony_ci 1804bf215546Sopenharmony_ci if ((srcHeight - 2 * border > 1) && 1805bf215546Sopenharmony_ci target != GL_TEXTURE_1D_ARRAY_EXT && 1806bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_1D_ARRAY_EXT) { 1807bf215546Sopenharmony_ci *dstHeight = (srcHeight - 2 * border) / 2 + 2 * border; 1808bf215546Sopenharmony_ci } 1809bf215546Sopenharmony_ci else { 1810bf215546Sopenharmony_ci *dstHeight = srcHeight; /* can't go smaller */ 1811bf215546Sopenharmony_ci } 1812bf215546Sopenharmony_ci 1813bf215546Sopenharmony_ci if ((srcDepth - 2 * border > 1) && 1814bf215546Sopenharmony_ci target != GL_TEXTURE_2D_ARRAY_EXT && 1815bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_2D_ARRAY_EXT && 1816bf215546Sopenharmony_ci target != GL_TEXTURE_CUBE_MAP_ARRAY && 1817bf215546Sopenharmony_ci target != GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) { 1818bf215546Sopenharmony_ci *dstDepth = (srcDepth - 2 * border) / 2 + 2 * border; 1819bf215546Sopenharmony_ci } 1820bf215546Sopenharmony_ci else { 1821bf215546Sopenharmony_ci *dstDepth = srcDepth; /* can't go smaller */ 1822bf215546Sopenharmony_ci } 1823bf215546Sopenharmony_ci 1824bf215546Sopenharmony_ci if (*dstWidth == srcWidth && 1825bf215546Sopenharmony_ci *dstHeight == srcHeight && 1826bf215546Sopenharmony_ci *dstDepth == srcDepth) { 1827bf215546Sopenharmony_ci return GL_FALSE; 1828bf215546Sopenharmony_ci } 1829bf215546Sopenharmony_ci else { 1830bf215546Sopenharmony_ci return GL_TRUE; 1831bf215546Sopenharmony_ci } 1832bf215546Sopenharmony_ci} 1833bf215546Sopenharmony_ci 1834bf215546Sopenharmony_ci 1835bf215546Sopenharmony_ci/** 1836bf215546Sopenharmony_ci * Helper function for mipmap generation. 1837bf215546Sopenharmony_ci * Make sure the specified destination mipmap level is the right size/format 1838bf215546Sopenharmony_ci * for mipmap generation. If not, (re) allocate it. 1839bf215546Sopenharmony_ci * \return GL_TRUE if successful, GL_FALSE if mipmap generation should stop 1840bf215546Sopenharmony_ci */ 1841bf215546Sopenharmony_cistatic GLboolean 1842bf215546Sopenharmony_ciprepare_mipmap_level(struct gl_context *ctx, 1843bf215546Sopenharmony_ci struct gl_texture_object *texObj, GLuint level, 1844bf215546Sopenharmony_ci GLsizei width, GLsizei height, GLsizei depth, 1845bf215546Sopenharmony_ci GLsizei border, GLenum intFormat, mesa_format format) 1846bf215546Sopenharmony_ci{ 1847bf215546Sopenharmony_ci const GLuint numFaces = _mesa_num_tex_faces(texObj->Target); 1848bf215546Sopenharmony_ci GLuint face; 1849bf215546Sopenharmony_ci 1850bf215546Sopenharmony_ci if (texObj->Immutable) { 1851bf215546Sopenharmony_ci /* The texture was created with glTexStorage() so the number/size of 1852bf215546Sopenharmony_ci * mipmap levels is fixed and the storage for all images is already 1853bf215546Sopenharmony_ci * allocated. 1854bf215546Sopenharmony_ci */ 1855bf215546Sopenharmony_ci if (!texObj->Image[0][level]) { 1856bf215546Sopenharmony_ci /* No more levels to create - we're done */ 1857bf215546Sopenharmony_ci return GL_FALSE; 1858bf215546Sopenharmony_ci } 1859bf215546Sopenharmony_ci else { 1860bf215546Sopenharmony_ci /* Nothing to do - the texture memory must have already been 1861bf215546Sopenharmony_ci * allocated to the right size so we're all set. 1862bf215546Sopenharmony_ci */ 1863bf215546Sopenharmony_ci return GL_TRUE; 1864bf215546Sopenharmony_ci } 1865bf215546Sopenharmony_ci } 1866bf215546Sopenharmony_ci 1867bf215546Sopenharmony_ci for (face = 0; face < numFaces; face++) { 1868bf215546Sopenharmony_ci struct gl_texture_image *dstImage; 1869bf215546Sopenharmony_ci const GLenum target = _mesa_cube_face_target(texObj->Target, face); 1870bf215546Sopenharmony_ci 1871bf215546Sopenharmony_ci dstImage = _mesa_get_tex_image(ctx, texObj, target, level); 1872bf215546Sopenharmony_ci if (!dstImage) { 1873bf215546Sopenharmony_ci /* out of memory */ 1874bf215546Sopenharmony_ci return GL_FALSE; 1875bf215546Sopenharmony_ci } 1876bf215546Sopenharmony_ci 1877bf215546Sopenharmony_ci if (dstImage->Width != width || 1878bf215546Sopenharmony_ci dstImage->Height != height || 1879bf215546Sopenharmony_ci dstImage->Depth != depth || 1880bf215546Sopenharmony_ci dstImage->Border != border || 1881bf215546Sopenharmony_ci dstImage->InternalFormat != intFormat || 1882bf215546Sopenharmony_ci dstImage->TexFormat != format) { 1883bf215546Sopenharmony_ci /* need to (re)allocate image */ 1884bf215546Sopenharmony_ci st_FreeTextureImageBuffer(ctx, dstImage); 1885bf215546Sopenharmony_ci 1886bf215546Sopenharmony_ci _mesa_init_teximage_fields(ctx, dstImage, 1887bf215546Sopenharmony_ci width, height, depth, 1888bf215546Sopenharmony_ci border, intFormat, format); 1889bf215546Sopenharmony_ci 1890bf215546Sopenharmony_ci st_AllocTextureImageBuffer(ctx, dstImage); 1891bf215546Sopenharmony_ci 1892bf215546Sopenharmony_ci /* in case the mipmap level is part of an FBO: */ 1893bf215546Sopenharmony_ci _mesa_update_fbo_texture(ctx, texObj, face, level); 1894bf215546Sopenharmony_ci 1895bf215546Sopenharmony_ci ctx->NewState |= _NEW_TEXTURE_OBJECT; 1896bf215546Sopenharmony_ci ctx->PopAttribState |= GL_TEXTURE_BIT; 1897bf215546Sopenharmony_ci } 1898bf215546Sopenharmony_ci } 1899bf215546Sopenharmony_ci 1900bf215546Sopenharmony_ci return GL_TRUE; 1901bf215546Sopenharmony_ci} 1902bf215546Sopenharmony_ci 1903bf215546Sopenharmony_ci 1904bf215546Sopenharmony_ci/** 1905bf215546Sopenharmony_ci * Prepare all mipmap levels beyond 'baseLevel' for mipmap generation. 1906bf215546Sopenharmony_ci * When finished, all the gl_texture_image structures for the smaller 1907bf215546Sopenharmony_ci * mipmap levels will be consistent with the base level (in terms of 1908bf215546Sopenharmony_ci * dimensions, format, etc). 1909bf215546Sopenharmony_ci */ 1910bf215546Sopenharmony_civoid 1911bf215546Sopenharmony_ci_mesa_prepare_mipmap_levels(struct gl_context *ctx, 1912bf215546Sopenharmony_ci struct gl_texture_object *texObj, 1913bf215546Sopenharmony_ci unsigned baseLevel, unsigned maxLevel) 1914bf215546Sopenharmony_ci{ 1915bf215546Sopenharmony_ci const struct gl_texture_image *baseImage = 1916bf215546Sopenharmony_ci _mesa_select_tex_image(texObj, texObj->Target, baseLevel); 1917bf215546Sopenharmony_ci 1918bf215546Sopenharmony_ci if (baseImage == NULL) 1919bf215546Sopenharmony_ci return; 1920bf215546Sopenharmony_ci 1921bf215546Sopenharmony_ci const GLint border = 0; 1922bf215546Sopenharmony_ci GLint width = baseImage->Width; 1923bf215546Sopenharmony_ci GLint height = baseImage->Height; 1924bf215546Sopenharmony_ci GLint depth = baseImage->Depth; 1925bf215546Sopenharmony_ci const GLenum intFormat = baseImage->InternalFormat; 1926bf215546Sopenharmony_ci const mesa_format texFormat = baseImage->TexFormat; 1927bf215546Sopenharmony_ci GLint newWidth, newHeight, newDepth; 1928bf215546Sopenharmony_ci 1929bf215546Sopenharmony_ci /* Prepare baseLevel + 1, baseLevel + 2, ... */ 1930bf215546Sopenharmony_ci for (unsigned level = baseLevel + 1; level <= maxLevel; level++) { 1931bf215546Sopenharmony_ci if (!_mesa_next_mipmap_level_size(texObj->Target, border, 1932bf215546Sopenharmony_ci width, height, depth, 1933bf215546Sopenharmony_ci &newWidth, &newHeight, &newDepth)) { 1934bf215546Sopenharmony_ci /* all done */ 1935bf215546Sopenharmony_ci break; 1936bf215546Sopenharmony_ci } 1937bf215546Sopenharmony_ci 1938bf215546Sopenharmony_ci if (!prepare_mipmap_level(ctx, texObj, level, 1939bf215546Sopenharmony_ci newWidth, newHeight, newDepth, 1940bf215546Sopenharmony_ci border, intFormat, texFormat)) { 1941bf215546Sopenharmony_ci break; 1942bf215546Sopenharmony_ci } 1943bf215546Sopenharmony_ci 1944bf215546Sopenharmony_ci width = newWidth; 1945bf215546Sopenharmony_ci height = newHeight; 1946bf215546Sopenharmony_ci depth = newDepth; 1947bf215546Sopenharmony_ci } 1948bf215546Sopenharmony_ci} 1949bf215546Sopenharmony_ci 1950bf215546Sopenharmony_ci 1951bf215546Sopenharmony_cistatic void 1952bf215546Sopenharmony_cigenerate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, 1953bf215546Sopenharmony_ci struct gl_texture_object *texObj, 1954bf215546Sopenharmony_ci const struct gl_texture_image *srcImage, 1955bf215546Sopenharmony_ci GLuint maxLevel) 1956bf215546Sopenharmony_ci{ 1957bf215546Sopenharmony_ci GLuint level; 1958bf215546Sopenharmony_ci GLenum datatype; 1959bf215546Sopenharmony_ci GLuint comps; 1960bf215546Sopenharmony_ci 1961bf215546Sopenharmony_ci _mesa_uncompressed_format_to_type_and_comps(srcImage->TexFormat, &datatype, &comps); 1962bf215546Sopenharmony_ci 1963bf215546Sopenharmony_ci for (level = texObj->Attrib.BaseLevel; level < maxLevel; level++) { 1964bf215546Sopenharmony_ci /* generate image[level+1] from image[level] */ 1965bf215546Sopenharmony_ci struct gl_texture_image *srcImage, *dstImage; 1966bf215546Sopenharmony_ci GLint srcRowStride, dstRowStride; 1967bf215546Sopenharmony_ci GLint srcWidth, srcHeight, srcDepth; 1968bf215546Sopenharmony_ci GLint dstWidth, dstHeight, dstDepth; 1969bf215546Sopenharmony_ci GLint border; 1970bf215546Sopenharmony_ci GLint slice; 1971bf215546Sopenharmony_ci GLubyte **srcMaps, **dstMaps; 1972bf215546Sopenharmony_ci GLboolean success = GL_TRUE; 1973bf215546Sopenharmony_ci 1974bf215546Sopenharmony_ci /* get src image parameters */ 1975bf215546Sopenharmony_ci srcImage = _mesa_select_tex_image(texObj, target, level); 1976bf215546Sopenharmony_ci assert(srcImage); 1977bf215546Sopenharmony_ci srcWidth = srcImage->Width; 1978bf215546Sopenharmony_ci srcHeight = srcImage->Height; 1979bf215546Sopenharmony_ci srcDepth = srcImage->Depth; 1980bf215546Sopenharmony_ci border = srcImage->Border; 1981bf215546Sopenharmony_ci 1982bf215546Sopenharmony_ci /* get dest gl_texture_image */ 1983bf215546Sopenharmony_ci dstImage = _mesa_select_tex_image(texObj, target, level + 1); 1984bf215546Sopenharmony_ci if (!dstImage) { 1985bf215546Sopenharmony_ci break; 1986bf215546Sopenharmony_ci } 1987bf215546Sopenharmony_ci dstWidth = dstImage->Width; 1988bf215546Sopenharmony_ci dstHeight = dstImage->Height; 1989bf215546Sopenharmony_ci dstDepth = dstImage->Depth; 1990bf215546Sopenharmony_ci 1991bf215546Sopenharmony_ci if (target == GL_TEXTURE_1D_ARRAY) { 1992bf215546Sopenharmony_ci srcDepth = srcHeight; 1993bf215546Sopenharmony_ci dstDepth = dstHeight; 1994bf215546Sopenharmony_ci srcHeight = 1; 1995bf215546Sopenharmony_ci dstHeight = 1; 1996bf215546Sopenharmony_ci } 1997bf215546Sopenharmony_ci 1998bf215546Sopenharmony_ci /* Map src texture image slices */ 1999bf215546Sopenharmony_ci srcMaps = calloc(srcDepth, sizeof(GLubyte *)); 2000bf215546Sopenharmony_ci if (srcMaps) { 2001bf215546Sopenharmony_ci for (slice = 0; slice < srcDepth; slice++) { 2002bf215546Sopenharmony_ci st_MapTextureImage(ctx, srcImage, slice, 2003bf215546Sopenharmony_ci 0, 0, srcWidth, srcHeight, 2004bf215546Sopenharmony_ci GL_MAP_READ_BIT, 2005bf215546Sopenharmony_ci &srcMaps[slice], &srcRowStride); 2006bf215546Sopenharmony_ci if (!srcMaps[slice]) { 2007bf215546Sopenharmony_ci success = GL_FALSE; 2008bf215546Sopenharmony_ci break; 2009bf215546Sopenharmony_ci } 2010bf215546Sopenharmony_ci } 2011bf215546Sopenharmony_ci } 2012bf215546Sopenharmony_ci else { 2013bf215546Sopenharmony_ci success = GL_FALSE; 2014bf215546Sopenharmony_ci } 2015bf215546Sopenharmony_ci 2016bf215546Sopenharmony_ci /* Map dst texture image slices */ 2017bf215546Sopenharmony_ci dstMaps = calloc(dstDepth, sizeof(GLubyte *)); 2018bf215546Sopenharmony_ci if (dstMaps) { 2019bf215546Sopenharmony_ci for (slice = 0; slice < dstDepth; slice++) { 2020bf215546Sopenharmony_ci st_MapTextureImage(ctx, dstImage, slice, 2021bf215546Sopenharmony_ci 0, 0, dstWidth, dstHeight, 2022bf215546Sopenharmony_ci GL_MAP_WRITE_BIT, 2023bf215546Sopenharmony_ci &dstMaps[slice], &dstRowStride); 2024bf215546Sopenharmony_ci if (!dstMaps[slice]) { 2025bf215546Sopenharmony_ci success = GL_FALSE; 2026bf215546Sopenharmony_ci break; 2027bf215546Sopenharmony_ci } 2028bf215546Sopenharmony_ci } 2029bf215546Sopenharmony_ci } 2030bf215546Sopenharmony_ci else { 2031bf215546Sopenharmony_ci success = GL_FALSE; 2032bf215546Sopenharmony_ci } 2033bf215546Sopenharmony_ci 2034bf215546Sopenharmony_ci if (success) { 2035bf215546Sopenharmony_ci /* generate one mipmap level (for 1D/2D/3D/array/etc texture) */ 2036bf215546Sopenharmony_ci _mesa_generate_mipmap_level(target, datatype, comps, border, 2037bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 2038bf215546Sopenharmony_ci (const GLubyte **) srcMaps, srcRowStride, 2039bf215546Sopenharmony_ci dstWidth, dstHeight, dstDepth, 2040bf215546Sopenharmony_ci dstMaps, dstRowStride); 2041bf215546Sopenharmony_ci } 2042bf215546Sopenharmony_ci 2043bf215546Sopenharmony_ci /* Unmap src image slices */ 2044bf215546Sopenharmony_ci if (srcMaps) { 2045bf215546Sopenharmony_ci for (slice = 0; slice < srcDepth; slice++) { 2046bf215546Sopenharmony_ci if (srcMaps[slice]) { 2047bf215546Sopenharmony_ci st_UnmapTextureImage(ctx, srcImage, slice); 2048bf215546Sopenharmony_ci } 2049bf215546Sopenharmony_ci } 2050bf215546Sopenharmony_ci free(srcMaps); 2051bf215546Sopenharmony_ci } 2052bf215546Sopenharmony_ci 2053bf215546Sopenharmony_ci /* Unmap dst image slices */ 2054bf215546Sopenharmony_ci if (dstMaps) { 2055bf215546Sopenharmony_ci for (slice = 0; slice < dstDepth; slice++) { 2056bf215546Sopenharmony_ci if (dstMaps[slice]) { 2057bf215546Sopenharmony_ci st_UnmapTextureImage(ctx, dstImage, slice); 2058bf215546Sopenharmony_ci } 2059bf215546Sopenharmony_ci } 2060bf215546Sopenharmony_ci free(dstMaps); 2061bf215546Sopenharmony_ci } 2062bf215546Sopenharmony_ci 2063bf215546Sopenharmony_ci if (!success) { 2064bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "mipmap generation"); 2065bf215546Sopenharmony_ci break; 2066bf215546Sopenharmony_ci } 2067bf215546Sopenharmony_ci } /* loop over mipmap levels */ 2068bf215546Sopenharmony_ci} 2069bf215546Sopenharmony_ci 2070bf215546Sopenharmony_ci 2071bf215546Sopenharmony_cistatic void 2072bf215546Sopenharmony_cigenerate_mipmap_compressed(struct gl_context *ctx, GLenum target, 2073bf215546Sopenharmony_ci struct gl_texture_object *texObj, 2074bf215546Sopenharmony_ci struct gl_texture_image *srcImage, 2075bf215546Sopenharmony_ci GLuint maxLevel) 2076bf215546Sopenharmony_ci{ 2077bf215546Sopenharmony_ci GLuint level; 2078bf215546Sopenharmony_ci mesa_format temp_format; 2079bf215546Sopenharmony_ci GLint components; 2080bf215546Sopenharmony_ci GLuint temp_src_row_stride, temp_src_img_stride; /* in bytes */ 2081bf215546Sopenharmony_ci GLubyte *temp_src = NULL, *temp_dst = NULL; 2082bf215546Sopenharmony_ci GLenum temp_datatype; 2083bf215546Sopenharmony_ci GLenum temp_base_format; 2084bf215546Sopenharmony_ci GLubyte **temp_src_slices = NULL, **temp_dst_slices = NULL; 2085bf215546Sopenharmony_ci 2086bf215546Sopenharmony_ci /* only two types of compressed textures at this time */ 2087bf215546Sopenharmony_ci assert(texObj->Target == GL_TEXTURE_2D || 2088bf215546Sopenharmony_ci texObj->Target == GL_TEXTURE_2D_ARRAY || 2089bf215546Sopenharmony_ci texObj->Target == GL_TEXTURE_CUBE_MAP || 2090bf215546Sopenharmony_ci texObj->Target == GL_TEXTURE_CUBE_MAP_ARRAY); 2091bf215546Sopenharmony_ci 2092bf215546Sopenharmony_ci /* 2093bf215546Sopenharmony_ci * Choose a format for the temporary, uncompressed base image. 2094bf215546Sopenharmony_ci * Then, get number of components, choose temporary image datatype, 2095bf215546Sopenharmony_ci * and get base format. 2096bf215546Sopenharmony_ci */ 2097bf215546Sopenharmony_ci temp_format = _mesa_get_uncompressed_format(srcImage->TexFormat); 2098bf215546Sopenharmony_ci 2099bf215546Sopenharmony_ci components = _mesa_format_num_components(temp_format); 2100bf215546Sopenharmony_ci 2101bf215546Sopenharmony_ci switch (_mesa_get_format_datatype(srcImage->TexFormat)) { 2102bf215546Sopenharmony_ci case GL_FLOAT: 2103bf215546Sopenharmony_ci temp_datatype = GL_FLOAT; 2104bf215546Sopenharmony_ci break; 2105bf215546Sopenharmony_ci case GL_SIGNED_NORMALIZED: 2106bf215546Sopenharmony_ci /* Revisit this if we get compressed formats with >8 bits per component */ 2107bf215546Sopenharmony_ci temp_datatype = GL_BYTE; 2108bf215546Sopenharmony_ci break; 2109bf215546Sopenharmony_ci default: 2110bf215546Sopenharmony_ci temp_datatype = GL_UNSIGNED_BYTE; 2111bf215546Sopenharmony_ci } 2112bf215546Sopenharmony_ci 2113bf215546Sopenharmony_ci temp_base_format = _mesa_get_format_base_format(temp_format); 2114bf215546Sopenharmony_ci 2115bf215546Sopenharmony_ci 2116bf215546Sopenharmony_ci /* allocate storage for the temporary, uncompressed image */ 2117bf215546Sopenharmony_ci temp_src_row_stride = _mesa_format_row_stride(temp_format, srcImage->Width); 2118bf215546Sopenharmony_ci temp_src_img_stride = _mesa_format_image_size(temp_format, srcImage->Width, 2119bf215546Sopenharmony_ci srcImage->Height, 1); 2120bf215546Sopenharmony_ci temp_src = malloc(temp_src_img_stride * srcImage->Depth); 2121bf215546Sopenharmony_ci 2122bf215546Sopenharmony_ci /* Allocate storage for arrays of slice pointers */ 2123bf215546Sopenharmony_ci temp_src_slices = malloc(srcImage->Depth * sizeof(GLubyte *)); 2124bf215546Sopenharmony_ci temp_dst_slices = malloc(srcImage->Depth * sizeof(GLubyte *)); 2125bf215546Sopenharmony_ci 2126bf215546Sopenharmony_ci if (!temp_src || !temp_src_slices || !temp_dst_slices) { 2127bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 2128bf215546Sopenharmony_ci goto end; 2129bf215546Sopenharmony_ci } 2130bf215546Sopenharmony_ci 2131bf215546Sopenharmony_ci /* decompress base image to the temporary src buffer */ 2132bf215546Sopenharmony_ci { 2133bf215546Sopenharmony_ci /* save pixel packing mode */ 2134bf215546Sopenharmony_ci struct gl_pixelstore_attrib save = ctx->Pack; 2135bf215546Sopenharmony_ci /* use default/tight packing parameters */ 2136bf215546Sopenharmony_ci ctx->Pack = ctx->DefaultPacking; 2137bf215546Sopenharmony_ci 2138bf215546Sopenharmony_ci /* Get the uncompressed image */ 2139bf215546Sopenharmony_ci assert(srcImage->Level == texObj->Attrib.BaseLevel); 2140bf215546Sopenharmony_ci st_GetTexSubImage(ctx, 2141bf215546Sopenharmony_ci 0, 0, 0, 2142bf215546Sopenharmony_ci srcImage->Width, srcImage->Height, 2143bf215546Sopenharmony_ci srcImage->Depth, 2144bf215546Sopenharmony_ci temp_base_format, temp_datatype, 2145bf215546Sopenharmony_ci temp_src, srcImage); 2146bf215546Sopenharmony_ci /* restore packing mode */ 2147bf215546Sopenharmony_ci ctx->Pack = save; 2148bf215546Sopenharmony_ci } 2149bf215546Sopenharmony_ci 2150bf215546Sopenharmony_ci for (level = texObj->Attrib.BaseLevel; level < maxLevel; level++) { 2151bf215546Sopenharmony_ci /* generate image[level+1] from image[level] */ 2152bf215546Sopenharmony_ci const struct gl_texture_image *srcImage; 2153bf215546Sopenharmony_ci struct gl_texture_image *dstImage; 2154bf215546Sopenharmony_ci GLint srcWidth, srcHeight, srcDepth; 2155bf215546Sopenharmony_ci GLint dstWidth, dstHeight, dstDepth; 2156bf215546Sopenharmony_ci GLint border; 2157bf215546Sopenharmony_ci GLuint temp_dst_row_stride, temp_dst_img_stride; /* in bytes */ 2158bf215546Sopenharmony_ci GLint i; 2159bf215546Sopenharmony_ci 2160bf215546Sopenharmony_ci /* get src image parameters */ 2161bf215546Sopenharmony_ci srcImage = _mesa_select_tex_image(texObj, target, level); 2162bf215546Sopenharmony_ci assert(srcImage); 2163bf215546Sopenharmony_ci srcWidth = srcImage->Width; 2164bf215546Sopenharmony_ci srcHeight = srcImage->Height; 2165bf215546Sopenharmony_ci srcDepth = srcImage->Depth; 2166bf215546Sopenharmony_ci border = srcImage->Border; 2167bf215546Sopenharmony_ci 2168bf215546Sopenharmony_ci /* get dest gl_texture_image */ 2169bf215546Sopenharmony_ci dstImage = _mesa_select_tex_image(texObj, target, level + 1); 2170bf215546Sopenharmony_ci if (!dstImage) { 2171bf215546Sopenharmony_ci break; 2172bf215546Sopenharmony_ci } 2173bf215546Sopenharmony_ci dstWidth = dstImage->Width; 2174bf215546Sopenharmony_ci dstHeight = dstImage->Height; 2175bf215546Sopenharmony_ci dstDepth = dstImage->Depth; 2176bf215546Sopenharmony_ci 2177bf215546Sopenharmony_ci /* Compute dst image strides and alloc memory on first iteration */ 2178bf215546Sopenharmony_ci temp_dst_row_stride = _mesa_format_row_stride(temp_format, dstWidth); 2179bf215546Sopenharmony_ci temp_dst_img_stride = _mesa_format_image_size(temp_format, dstWidth, 2180bf215546Sopenharmony_ci dstHeight, 1); 2181bf215546Sopenharmony_ci if (!temp_dst) { 2182bf215546Sopenharmony_ci temp_dst = malloc(temp_dst_img_stride * dstDepth); 2183bf215546Sopenharmony_ci if (!temp_dst) { 2184bf215546Sopenharmony_ci _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps"); 2185bf215546Sopenharmony_ci goto end; 2186bf215546Sopenharmony_ci } 2187bf215546Sopenharmony_ci } 2188bf215546Sopenharmony_ci 2189bf215546Sopenharmony_ci /* for 2D arrays, setup array[depth] of slice pointers */ 2190bf215546Sopenharmony_ci for (i = 0; i < srcDepth; i++) { 2191bf215546Sopenharmony_ci temp_src_slices[i] = temp_src + temp_src_img_stride * i; 2192bf215546Sopenharmony_ci } 2193bf215546Sopenharmony_ci for (i = 0; i < dstDepth; i++) { 2194bf215546Sopenharmony_ci temp_dst_slices[i] = temp_dst + temp_dst_img_stride * i; 2195bf215546Sopenharmony_ci } 2196bf215546Sopenharmony_ci 2197bf215546Sopenharmony_ci /* Rescale src image to dest image. 2198bf215546Sopenharmony_ci * This will loop over the slices of a 2D array. 2199bf215546Sopenharmony_ci */ 2200bf215546Sopenharmony_ci _mesa_generate_mipmap_level(target, temp_datatype, components, border, 2201bf215546Sopenharmony_ci srcWidth, srcHeight, srcDepth, 2202bf215546Sopenharmony_ci (const GLubyte **) temp_src_slices, 2203bf215546Sopenharmony_ci temp_src_row_stride, 2204bf215546Sopenharmony_ci dstWidth, dstHeight, dstDepth, 2205bf215546Sopenharmony_ci temp_dst_slices, temp_dst_row_stride); 2206bf215546Sopenharmony_ci 2207bf215546Sopenharmony_ci /* The image space was allocated above so use glTexSubImage now */ 2208bf215546Sopenharmony_ci st_TexSubImage(ctx, 2, dstImage, 2209bf215546Sopenharmony_ci 0, 0, 0, dstWidth, dstHeight, dstDepth, 2210bf215546Sopenharmony_ci temp_base_format, temp_datatype, 2211bf215546Sopenharmony_ci temp_dst, &ctx->DefaultPacking); 2212bf215546Sopenharmony_ci 2213bf215546Sopenharmony_ci /* swap src and dest pointers */ 2214bf215546Sopenharmony_ci { 2215bf215546Sopenharmony_ci GLubyte *temp = temp_src; 2216bf215546Sopenharmony_ci temp_src = temp_dst; 2217bf215546Sopenharmony_ci temp_dst = temp; 2218bf215546Sopenharmony_ci temp_src_row_stride = temp_dst_row_stride; 2219bf215546Sopenharmony_ci temp_src_img_stride = temp_dst_img_stride; 2220bf215546Sopenharmony_ci } 2221bf215546Sopenharmony_ci } /* loop over mipmap levels */ 2222bf215546Sopenharmony_ci 2223bf215546Sopenharmony_ciend: 2224bf215546Sopenharmony_ci free(temp_src); 2225bf215546Sopenharmony_ci free(temp_dst); 2226bf215546Sopenharmony_ci free(temp_src_slices); 2227bf215546Sopenharmony_ci free(temp_dst_slices); 2228bf215546Sopenharmony_ci} 2229bf215546Sopenharmony_ci 2230bf215546Sopenharmony_ci/** 2231bf215546Sopenharmony_ci * Automatic mipmap generation. 2232bf215546Sopenharmony_ci * This is the fallback/default function for mipmap generation. 2233bf215546Sopenharmony_ci * Generate a complete set of mipmaps from texObj's BaseLevel image. 2234bf215546Sopenharmony_ci * Stop at texObj's MaxLevel or when we get to the 1x1 texture. 2235bf215546Sopenharmony_ci * For cube maps, target will be one of 2236bf215546Sopenharmony_ci * GL_TEXTURE_CUBE_MAP_POSITIVE/NEGATIVE_X/Y/Z; never GL_TEXTURE_CUBE_MAP. 2237bf215546Sopenharmony_ci */ 2238bf215546Sopenharmony_civoid 2239bf215546Sopenharmony_ci_mesa_generate_mipmap(struct gl_context *ctx, GLenum target, 2240bf215546Sopenharmony_ci struct gl_texture_object *texObj) 2241bf215546Sopenharmony_ci{ 2242bf215546Sopenharmony_ci struct gl_texture_image *srcImage; 2243bf215546Sopenharmony_ci GLint maxLevel; 2244bf215546Sopenharmony_ci 2245bf215546Sopenharmony_ci assert(texObj); 2246bf215546Sopenharmony_ci srcImage = _mesa_select_tex_image(texObj, target, texObj->Attrib.BaseLevel); 2247bf215546Sopenharmony_ci assert(srcImage); 2248bf215546Sopenharmony_ci 2249bf215546Sopenharmony_ci maxLevel = _mesa_max_texture_levels(ctx, texObj->Target) - 1; 2250bf215546Sopenharmony_ci assert(maxLevel >= 0); /* bad target */ 2251bf215546Sopenharmony_ci 2252bf215546Sopenharmony_ci maxLevel = MIN2(maxLevel, texObj->Attrib.MaxLevel); 2253bf215546Sopenharmony_ci 2254bf215546Sopenharmony_ci _mesa_prepare_mipmap_levels(ctx, texObj, texObj->Attrib.BaseLevel, maxLevel); 2255bf215546Sopenharmony_ci 2256bf215546Sopenharmony_ci if (_mesa_is_format_compressed(srcImage->TexFormat)) { 2257bf215546Sopenharmony_ci generate_mipmap_compressed(ctx, target, texObj, srcImage, maxLevel); 2258bf215546Sopenharmony_ci } else { 2259bf215546Sopenharmony_ci generate_mipmap_uncompressed(ctx, target, texObj, srcImage, maxLevel); 2260bf215546Sopenharmony_ci } 2261bf215546Sopenharmony_ci} 2262