Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

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