1f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian/**************************************************************************
2f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
3f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
4f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * All Rights Reserved.
59c8db8685432fedd068157795422764ce96b89a0Brian Paul * Copyright 2008  VMware, Inc.  All rights reserved.
6f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
7f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Permission is hereby granted, free of charge, to any person obtaining a
8f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * copy of this software and associated documentation files (the
9f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * "Software"), to deal in the Software without restriction, including
10f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * without limitation the rights to use, copy, modify, merge, publish,
11f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * distribute, sub license, and/or sell copies of the Software, and to
12f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * permit persons to whom the Software is furnished to do so, subject to
13f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * the following conditions:
14f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
15f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * The above copyright notice and this permission notice (including the
16f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * next paragraph) shall be included in all copies or substantial portions
17f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * of the Software.
18f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
19f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
27f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian **************************************************************************/
28f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
29f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian/**
30f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * @file
31f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Mipmap generation utility
32f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
33f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * @author Brian Paul
34f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian */
35f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
36f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
37f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian#include "pipe/p_context.h"
38ea4bf267e4b023b08043f91ac44592fed1736e7fJosé Fonseca#include "util/u_debug.h"
39f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian#include "pipe/p_defines.h"
4028486880ca3ec39419ccee0cb1a3bedc9ef7117cJosé Fonseca#include "util/u_inlines.h"
41f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian#include "pipe/p_shader_tokens.h"
425e27cd46c04a9e7b5904cc014bffd0f4daae31feMichel Dänzer#include "pipe/p_state.h"
43f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
44cceeab39ea541b1be1521114316d660a77769c2aMichal Krol#include "util/u_format.h"
454f25420bdd834e81a3e22733304efc5261c2998aBrian Paul#include "util/u_memory.h"
46f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian#include "util/u_draw_quad.h"
47f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian#include "util/u_gen_mipmap.h"
484bd2b74441092154f0d0048822c6e36cfcc183afBrian#include "util/u_simple_shaders.h"
49683e35f726a182ed9fc6b6d5cb07146eebe14deaKeith Whitwell#include "util/u_math.h"
504c61022b4a19f020ef8f6c635ecffa54a914fd7aMarek Olšák#include "util/u_texture.h"
514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#include "util/u_half.h"
524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger#include "util/u_surface.h"
53f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
547d95efde0a0e13e13c59444703bc47eb13926385Brian#include "cso_cache/cso_context.h"
557d95efde0a0e13e13c59444703bc47eb13926385Brian
56f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
57e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brianstruct gen_mipmap_state
58e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian{
59e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian   struct pipe_context *pipe;
607d95efde0a0e13e13c59444703bc47eb13926385Brian   struct cso_context *cso;
61e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian
6291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   struct pipe_blend_state blend_keep_color, blend_write_color;
6391cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   struct pipe_depth_stencil_alpha_state dsa_keep_depth, dsa_write_depth;
647d95efde0a0e13e13c59444703bc47eb13926385Brian   struct pipe_rasterizer_state rasterizer;
657d95efde0a0e13e13c59444703bc47eb13926385Brian   struct pipe_sampler_state sampler;
66ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   struct pipe_vertex_element velem[2];
67ba49fa39f3028d1ee44a999d84b29a0cfbfab0bdBrian
68ba49fa39f3028d1ee44a999d84b29a0cfbfab0bdBrian   void *vs;
6991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák
7091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   /** Not all are used, but simplifies code */
7191cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   void *fs_color[TGSI_TEXTURE_COUNT];
7291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   void *fs_depth[TGSI_TEXTURE_COUNT];
73309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
74287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *vbuf;  /**< quad vertices */
75d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   unsigned vbuf_slot;
76d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
77309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian   float vertices[4][2][4];   /**< vertex/texcoords for quad */
78e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian};
79e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian
80e5a20499d84ba8d270c3144f2c1c7615eeb077c7Brian
81de779c8d319b6269705cd7e6f2009243a771a2b9Brian
82de779c8d319b6269705cd7e6f2009243a771a2b9Brianenum dtype
83de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
840c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_UBYTE,
850c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_UBYTE_3_3_2,
860c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_USHORT,
870c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_USHORT_4_4_4_4,
880c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_USHORT_5_6_5,
890c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_USHORT_1_5_5_5_REV,
900c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_UINT,
910c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_FLOAT,
920c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   DTYPE_HALF_FLOAT
93de779c8d319b6269705cd7e6f2009243a771a2b9Brian};
94de779c8d319b6269705cd7e6f2009243a771a2b9Brian
95de779c8d319b6269705cd7e6f2009243a771a2b9Brian
964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheideggertypedef uint16_t half_float;
979c8db8685432fedd068157795422764ce96b89a0Brian Paul
989c8db8685432fedd068157795422764ce96b89a0Brian Paul
999c8db8685432fedd068157795422764ce96b89a0Brian Paul/**
1009c8db8685432fedd068157795422764ce96b89a0Brian Paul * \name Support macros for do_row and do_row_3d
1019c8db8685432fedd068157795422764ce96b89a0Brian Paul *
1029c8db8685432fedd068157795422764ce96b89a0Brian Paul * The macro madness is here for two reasons.  First, it compacts the code
1039c8db8685432fedd068157795422764ce96b89a0Brian Paul * slightly.  Second, it makes it much easier to adjust the specifics of the
1049c8db8685432fedd068157795422764ce96b89a0Brian Paul * filter to tune the rounding characteristics.
1059c8db8685432fedd068157795422764ce96b89a0Brian Paul */
1069c8db8685432fedd068157795422764ce96b89a0Brian Paul/*@{*/
1079c8db8685432fedd068157795422764ce96b89a0Brian Paul#define DECLARE_ROW_POINTERS(t, e) \
1089c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t(*rowA)[e] = (const t(*)[e]) srcRowA; \
1099c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t(*rowB)[e] = (const t(*)[e]) srcRowB; \
1109c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t(*rowC)[e] = (const t(*)[e]) srcRowC; \
1119c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t(*rowD)[e] = (const t(*)[e]) srcRowD; \
1129c8db8685432fedd068157795422764ce96b89a0Brian Paul      t(*dst)[e] = (t(*)[e]) dstRow
1139c8db8685432fedd068157795422764ce96b89a0Brian Paul
1149c8db8685432fedd068157795422764ce96b89a0Brian Paul#define DECLARE_ROW_POINTERS0(t) \
1159c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t *rowA = (const t *) srcRowA; \
1169c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t *rowB = (const t *) srcRowB; \
1179c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t *rowC = (const t *) srcRowC; \
1189c8db8685432fedd068157795422764ce96b89a0Brian Paul      const t *rowD = (const t *) srcRowD; \
1199c8db8685432fedd068157795422764ce96b89a0Brian Paul      t *dst = (t *) dstRow
1209c8db8685432fedd068157795422764ce96b89a0Brian Paul
1219c8db8685432fedd068157795422764ce96b89a0Brian Paul#define FILTER_SUM_3D(Aj, Ak, Bj, Bk, Cj, Ck, Dj, Dk) \
1229c8db8685432fedd068157795422764ce96b89a0Brian Paul   ((unsigned) Aj + (unsigned) Ak \
1239c8db8685432fedd068157795422764ce96b89a0Brian Paul    + (unsigned) Bj + (unsigned) Bk \
1249c8db8685432fedd068157795422764ce96b89a0Brian Paul    + (unsigned) Cj + (unsigned) Ck \
1259c8db8685432fedd068157795422764ce96b89a0Brian Paul    + (unsigned) Dj + (unsigned) Dk \
1269c8db8685432fedd068157795422764ce96b89a0Brian Paul    + 4) >> 3
1279c8db8685432fedd068157795422764ce96b89a0Brian Paul
1289c8db8685432fedd068157795422764ce96b89a0Brian Paul#define FILTER_3D(e) \
1299c8db8685432fedd068157795422764ce96b89a0Brian Paul   do { \
1309c8db8685432fedd068157795422764ce96b89a0Brian Paul      dst[i][e] = FILTER_SUM_3D(rowA[j][e], rowA[k][e], \
1319c8db8685432fedd068157795422764ce96b89a0Brian Paul                                rowB[j][e], rowB[k][e], \
1329c8db8685432fedd068157795422764ce96b89a0Brian Paul                                rowC[j][e], rowC[k][e], \
1339c8db8685432fedd068157795422764ce96b89a0Brian Paul                                rowD[j][e], rowD[k][e]); \
1349c8db8685432fedd068157795422764ce96b89a0Brian Paul   } while(0)
1354c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
1369c8db8685432fedd068157795422764ce96b89a0Brian Paul#define FILTER_F_3D(e) \
1379c8db8685432fedd068157795422764ce96b89a0Brian Paul   do { \
1389c8db8685432fedd068157795422764ce96b89a0Brian Paul      dst[i][e] = (rowA[j][e] + rowA[k][e] \
1399c8db8685432fedd068157795422764ce96b89a0Brian Paul                   + rowB[j][e] + rowB[k][e] \
1409c8db8685432fedd068157795422764ce96b89a0Brian Paul                   + rowC[j][e] + rowC[k][e] \
1419c8db8685432fedd068157795422764ce96b89a0Brian Paul                   + rowD[j][e] + rowD[k][e]) * 0.125F; \
1429c8db8685432fedd068157795422764ce96b89a0Brian Paul   } while(0)
1439c8db8685432fedd068157795422764ce96b89a0Brian Paul
1449c8db8685432fedd068157795422764ce96b89a0Brian Paul#define FILTER_HF_3D(e) \
1459c8db8685432fedd068157795422764ce96b89a0Brian Paul   do { \
1464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float aj = util_half_to_float(rowA[j][e]); \
1474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float ak = util_half_to_float(rowA[k][e]); \
1484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float bj = util_half_to_float(rowB[j][e]); \
1494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float bk = util_half_to_float(rowB[k][e]); \
1504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float cj = util_half_to_float(rowC[j][e]); \
1514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float ck = util_half_to_float(rowC[k][e]); \
1524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float dj = util_half_to_float(rowD[j][e]); \
1534c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      const float dk = util_half_to_float(rowD[k][e]); \
1544c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dst[i][e] = util_float_to_half((aj + ak + bj + bk + cj + ck + dj + dk) \
1559c8db8685432fedd068157795422764ce96b89a0Brian Paul                                      * 0.125F); \
1569c8db8685432fedd068157795422764ce96b89a0Brian Paul   } while(0)
1579c8db8685432fedd068157795422764ce96b89a0Brian Paul/*@}*/
158de779c8d319b6269705cd7e6f2009243a771a2b9Brian
159de779c8d319b6269705cd7e6f2009243a771a2b9Brian
160de779c8d319b6269705cd7e6f2009243a771a2b9Brian/**
161de779c8d319b6269705cd7e6f2009243a771a2b9Brian * Average together two rows of a source image to produce a single new
162de779c8d319b6269705cd7e6f2009243a771a2b9Brian * row in the dest image.  It's legal for the two source rows to point
163de779c8d319b6269705cd7e6f2009243a771a2b9Brian * to the same data.  The source width must be equal to either the
164de779c8d319b6269705cd7e6f2009243a771a2b9Brian * dest width or two times the dest width.
165de779c8d319b6269705cd7e6f2009243a771a2b9Brian * \param datatype  GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, GL_FLOAT, etc.
166de779c8d319b6269705cd7e6f2009243a771a2b9Brian * \param comps  number of components per pixel (1..4)
167de779c8d319b6269705cd7e6f2009243a771a2b9Brian */
168de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
169de779c8d319b6269705cd7e6f2009243a771a2b9Briando_row(enum dtype datatype, uint comps, int srcWidth,
170de779c8d319b6269705cd7e6f2009243a771a2b9Brian       const void *srcRowA, const void *srcRowB,
171de779c8d319b6269705cd7e6f2009243a771a2b9Brian       int dstWidth, void *dstRow)
172de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
173de779c8d319b6269705cd7e6f2009243a771a2b9Brian   const uint k0 = (srcWidth == dstWidth) ? 0 : 1;
174de779c8d319b6269705cd7e6f2009243a771a2b9Brian   const uint colStride = (srcWidth == dstWidth) ? 1 : 2;
175de779c8d319b6269705cd7e6f2009243a771a2b9Brian
176de779c8d319b6269705cd7e6f2009243a771a2b9Brian   assert(comps >= 1);
177de779c8d319b6269705cd7e6f2009243a771a2b9Brian   assert(comps <= 4);
178de779c8d319b6269705cd7e6f2009243a771a2b9Brian
179de779c8d319b6269705cd7e6f2009243a771a2b9Brian   /* This assertion is no longer valid with non-power-of-2 textures
180de779c8d319b6269705cd7e6f2009243a771a2b9Brian   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
181de779c8d319b6269705cd7e6f2009243a771a2b9Brian   */
182de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1830c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   if (datatype == DTYPE_UBYTE && comps == 4) {
184de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
185de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowA)[4] = (const ubyte(*)[4]) srcRowA;
186de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowB)[4] = (const ubyte(*)[4]) srcRowB;
187de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte(*dst)[4] = (ubyte(*)[4]) dstRow;
188de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
189de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
190de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
191de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
192de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
193de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
194de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
195de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
1960c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_UBYTE && comps == 3) {
197de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
198de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowA)[3] = (const ubyte(*)[3]) srcRowA;
199de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowB)[3] = (const ubyte(*)[3]) srcRowB;
200de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte(*dst)[3] = (ubyte(*)[3]) dstRow;
201de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
202de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
203de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
204de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
205de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
206de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
207de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2080c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_UBYTE && comps == 2) {
209de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
210de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowA)[2] = (const ubyte(*)[2]) srcRowA;
211de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte(*rowB)[2] = (const ubyte(*)[2]) srcRowB;
212de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte(*dst)[2] = (ubyte(*)[2]) dstRow;
213de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
214de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
215de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) >> 2;
216de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) >> 2;
217de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
218de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2190c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_UBYTE && comps == 1) {
220de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
221de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte *rowA = (const ubyte *) srcRowA;
222de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte *rowB = (const ubyte *) srcRowB;
223de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte *dst = (ubyte *) dstRow;
224de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
225de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
226de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
227de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
228de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
229de779c8d319b6269705cd7e6f2009243a771a2b9Brian
2300c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT && comps == 4) {
231de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
232de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowA)[4] = (const ushort(*)[4]) srcRowA;
233de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowB)[4] = (const ushort(*)[4]) srcRowB;
234de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort(*dst)[4] = (ushort(*)[4]) dstRow;
235de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
236de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
237de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
238de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
239de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
240de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][3] = (rowA[j][3] + rowA[k][3] + rowB[j][3] + rowB[k][3]) / 4;
241de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
242de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2430c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT && comps == 3) {
244de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
245de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowA)[3] = (const ushort(*)[3]) srcRowA;
246de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowB)[3] = (const ushort(*)[3]) srcRowB;
247de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort(*dst)[3] = (ushort(*)[3]) dstRow;
248de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
249de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
250de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
251de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
252de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] + rowB[j][2] + rowB[k][2]) / 4;
253de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
254de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2550c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT && comps == 2) {
256de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
257de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowA)[2] = (const ushort(*)[2]) srcRowA;
258de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort(*rowB)[2] = (const ushort(*)[2]) srcRowB;
259de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort(*dst)[2] = (ushort(*)[2]) dstRow;
260de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
261de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
262de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] + rowB[j][0] + rowB[k][0]) / 4;
263de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] + rowB[j][1] + rowB[k][1]) / 4;
264de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
265de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2660c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT && comps == 1) {
267de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
268de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowA = (const ushort *) srcRowA;
269de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowB = (const ushort *) srcRowB;
270de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort *dst = (ushort *) dstRow;
271de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
272de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
273de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
274de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
275de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
276de779c8d319b6269705cd7e6f2009243a771a2b9Brian
2770c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_FLOAT && comps == 4) {
278de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
279de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowA)[4] = (const float(*)[4]) srcRowA;
280de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowB)[4] = (const float(*)[4]) srcRowB;
281de779c8d319b6269705cd7e6f2009243a771a2b9Brian      float(*dst)[4] = (float(*)[4]) dstRow;
282de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
283de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
284de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] +
285de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][0] + rowB[k][0]) * 0.25F;
286de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] +
287de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][1] + rowB[k][1]) * 0.25F;
288de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] +
289de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][2] + rowB[k][2]) * 0.25F;
290de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][3] = (rowA[j][3] + rowA[k][3] +
291de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][3] + rowB[k][3]) * 0.25F;
292de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
293de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
2940c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_FLOAT && comps == 3) {
295de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
296de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowA)[3] = (const float(*)[3]) srcRowA;
297de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowB)[3] = (const float(*)[3]) srcRowB;
298de779c8d319b6269705cd7e6f2009243a771a2b9Brian      float(*dst)[3] = (float(*)[3]) dstRow;
299de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
300de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
301de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] +
302de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][0] + rowB[k][0]) * 0.25F;
303de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] +
304de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][1] + rowB[k][1]) * 0.25F;
305de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][2] = (rowA[j][2] + rowA[k][2] +
306de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][2] + rowB[k][2]) * 0.25F;
307de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
308de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
3090c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_FLOAT && comps == 2) {
310de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
311de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowA)[2] = (const float(*)[2]) srcRowA;
312de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float(*rowB)[2] = (const float(*)[2]) srcRowB;
313de779c8d319b6269705cd7e6f2009243a771a2b9Brian      float(*dst)[2] = (float(*)[2]) dstRow;
314de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
315de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
316de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][0] = (rowA[j][0] + rowA[k][0] +
317de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][0] + rowB[k][0]) * 0.25F;
318de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i][1] = (rowA[j][1] + rowA[k][1] +
319de779c8d319b6269705cd7e6f2009243a771a2b9Brian                      rowB[j][1] + rowB[k][1]) * 0.25F;
320de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
321de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
3220c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_FLOAT && comps == 1) {
323de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
324de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float *rowA = (const float *) srcRowA;
325de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const float *rowB = (const float *) srcRowB;
326de779c8d319b6269705cd7e6f2009243a771a2b9Brian      float *dst = (float *) dstRow;
327de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
328de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
329de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
330de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
331de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
332de779c8d319b6269705cd7e6f2009243a771a2b9Brian
3334c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   else if (datatype == DTYPE_HALF_FLOAT && comps == 4) {
334de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k, comp;
335de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowA)[4] = (const half_float(*)[4]) srcRowA;
336de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowB)[4] = (const half_float(*)[4]) srcRowB;
337de779c8d319b6269705cd7e6f2009243a771a2b9Brian      half_float(*dst)[4] = (half_float(*)[4]) dstRow;
338de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
339de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
340de779c8d319b6269705cd7e6f2009243a771a2b9Brian         for (comp = 0; comp < 4; comp++) {
341de779c8d319b6269705cd7e6f2009243a771a2b9Brian            float aj, ak, bj, bk;
3424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            aj = util_half_to_float(rowA[j][comp]);
3434c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            ak = util_half_to_float(rowA[k][comp]);
3444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bj = util_half_to_float(rowB[j][comp]);
3454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bk = util_half_to_float(rowB[k][comp]);
3464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
347de779c8d319b6269705cd7e6f2009243a771a2b9Brian         }
348de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
349de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
3500c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_HALF_FLOAT && comps == 3) {
351de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k, comp;
352de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowA)[3] = (const half_float(*)[3]) srcRowA;
353de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowB)[3] = (const half_float(*)[3]) srcRowB;
354de779c8d319b6269705cd7e6f2009243a771a2b9Brian      half_float(*dst)[3] = (half_float(*)[3]) dstRow;
355de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
356de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
357de779c8d319b6269705cd7e6f2009243a771a2b9Brian         for (comp = 0; comp < 3; comp++) {
358de779c8d319b6269705cd7e6f2009243a771a2b9Brian            float aj, ak, bj, bk;
3594c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            aj = util_half_to_float(rowA[j][comp]);
3604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            ak = util_half_to_float(rowA[k][comp]);
3614c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bj = util_half_to_float(rowB[j][comp]);
3624c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bk = util_half_to_float(rowB[k][comp]);
3634c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
364de779c8d319b6269705cd7e6f2009243a771a2b9Brian         }
365de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
366de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
3670c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_HALF_FLOAT && comps == 2) {
368de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k, comp;
369de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowA)[2] = (const half_float(*)[2]) srcRowA;
370de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float(*rowB)[2] = (const half_float(*)[2]) srcRowB;
371de779c8d319b6269705cd7e6f2009243a771a2b9Brian      half_float(*dst)[2] = (half_float(*)[2]) dstRow;
372de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
373de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
374de779c8d319b6269705cd7e6f2009243a771a2b9Brian         for (comp = 0; comp < 2; comp++) {
375de779c8d319b6269705cd7e6f2009243a771a2b9Brian            float aj, ak, bj, bk;
3764c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            aj = util_half_to_float(rowA[j][comp]);
3774c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            ak = util_half_to_float(rowA[k][comp]);
3784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bj = util_half_to_float(rowB[j][comp]);
3794c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            bk = util_half_to_float(rowB[k][comp]);
3804c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            dst[i][comp] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
381de779c8d319b6269705cd7e6f2009243a771a2b9Brian         }
382de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
383de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
3840c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_HALF_FLOAT && comps == 1) {
385de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
386de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float *rowA = (const half_float *) srcRowA;
387de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const half_float *rowB = (const half_float *) srcRowB;
388de779c8d319b6269705cd7e6f2009243a771a2b9Brian      half_float *dst = (half_float *) dstRow;
389de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
390de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
391de779c8d319b6269705cd7e6f2009243a771a2b9Brian         float aj, ak, bj, bk;
3924c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         aj = util_half_to_float(rowA[j]);
3934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         ak = util_half_to_float(rowA[k]);
3944c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         bj = util_half_to_float(rowB[j]);
3954c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         bk = util_half_to_float(rowB[k]);
3964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         dst[i] = util_float_to_half((aj + ak + bj + bk) * 0.25F);
397de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
398de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
399de779c8d319b6269705cd7e6f2009243a771a2b9Brian
4000c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_UINT && comps == 1) {
401de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
402de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const uint *rowA = (const uint *) srcRowA;
403de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const uint *rowB = (const uint *) srcRowB;
404e8f8b12bb940794cef8eff52ae8c908ad0604161Brian      uint *dst = (uint *) dstRow;
405de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
406de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
407e8f8b12bb940794cef8eff52ae8c908ad0604161Brian         dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
408de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
409de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
410de779c8d319b6269705cd7e6f2009243a771a2b9Brian
4110c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT_5_6_5 && comps == 3) {
412de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
413de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowA = (const ushort *) srcRowA;
414de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowB = (const ushort *) srcRowB;
415de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort *dst = (ushort *) dstRow;
416de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
417de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
418de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr0 = rowA[j] & 0x1f;
419de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr1 = rowA[k] & 0x1f;
420de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr0 = rowB[j] & 0x1f;
421de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr1 = rowB[k] & 0x1f;
422de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg0 = (rowA[j] >> 5) & 0x3f;
423de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg1 = (rowA[k] >> 5) & 0x3f;
424de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg0 = (rowB[j] >> 5) & 0x3f;
425de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg1 = (rowB[k] >> 5) & 0x3f;
426de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb0 = (rowA[j] >> 11) & 0x1f;
427de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb1 = (rowA[k] >> 11) & 0x1f;
428de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb0 = (rowB[j] >> 11) & 0x1f;
429de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb1 = (rowB[k] >> 11) & 0x1f;
430de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
431de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
432de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
433de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (blue << 11) | (green << 5) | red;
434de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
435de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
4360c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT_4_4_4_4 && comps == 4) {
437de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
438de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowA = (const ushort *) srcRowA;
439de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowB = (const ushort *) srcRowB;
440de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort *dst = (ushort *) dstRow;
441de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
442de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
443de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr0 = rowA[j] & 0xf;
444de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr1 = rowA[k] & 0xf;
445de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr0 = rowB[j] & 0xf;
446de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr1 = rowB[k] & 0xf;
447de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg0 = (rowA[j] >> 4) & 0xf;
448de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg1 = (rowA[k] >> 4) & 0xf;
449de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg0 = (rowB[j] >> 4) & 0xf;
450de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg1 = (rowB[k] >> 4) & 0xf;
451de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb0 = (rowA[j] >> 8) & 0xf;
452de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb1 = (rowA[k] >> 8) & 0xf;
453de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb0 = (rowB[j] >> 8) & 0xf;
454de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb1 = (rowB[k] >> 8) & 0xf;
455de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAa0 = (rowA[j] >> 12) & 0xf;
456de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAa1 = (rowA[k] >> 12) & 0xf;
457de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBa0 = (rowB[j] >> 12) & 0xf;
458de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBa1 = (rowB[k] >> 12) & 0xf;
459de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
460de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
461de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
462de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
463de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
464de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
465de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
4660c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_USHORT_1_5_5_5_REV && comps == 4) {
467de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
468de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowA = (const ushort *) srcRowA;
469de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ushort *rowB = (const ushort *) srcRowB;
470de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ushort *dst = (ushort *) dstRow;
471de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
472de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
473de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr0 = rowA[j] & 0x1f;
474de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr1 = rowA[k] & 0x1f;
475de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr0 = rowB[j] & 0x1f;
476e8d80609883db4c827f8c25e816e588b025843c0Brian Paul         const int rowBr1 = rowB[k] & 0x1f;
477de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg0 = (rowA[j] >> 5) & 0x1f;
478de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg1 = (rowA[k] >> 5) & 0x1f;
479de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg0 = (rowB[j] >> 5) & 0x1f;
480de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg1 = (rowB[k] >> 5) & 0x1f;
481de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb0 = (rowA[j] >> 10) & 0x1f;
482de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb1 = (rowA[k] >> 10) & 0x1f;
483de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb0 = (rowB[j] >> 10) & 0x1f;
484de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb1 = (rowB[k] >> 10) & 0x1f;
485de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAa0 = (rowA[j] >> 15) & 0x1;
486de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAa1 = (rowA[k] >> 15) & 0x1;
487de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBa0 = (rowB[j] >> 15) & 0x1;
488de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBa1 = (rowB[k] >> 15) & 0x1;
489de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
490de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
491de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
492de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
493de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
494de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
495de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
4960c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if (datatype == DTYPE_UBYTE_3_3_2 && comps == 3) {
497de779c8d319b6269705cd7e6f2009243a771a2b9Brian      uint i, j, k;
498de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte *rowA = (const ubyte *) srcRowA;
499de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const ubyte *rowB = (const ubyte *) srcRowB;
500de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte *dst = (ubyte *) dstRow;
501de779c8d319b6269705cd7e6f2009243a771a2b9Brian      for (i = j = 0, k = k0; i < (uint) dstWidth;
502de779c8d319b6269705cd7e6f2009243a771a2b9Brian           i++, j += colStride, k += colStride) {
503de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr0 = rowA[j] & 0x3;
504de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAr1 = rowA[k] & 0x3;
505de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr0 = rowB[j] & 0x3;
506de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBr1 = rowB[k] & 0x3;
507de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg0 = (rowA[j] >> 2) & 0x7;
508de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAg1 = (rowA[k] >> 2) & 0x7;
509de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg0 = (rowB[j] >> 2) & 0x7;
510de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBg1 = (rowB[k] >> 2) & 0x7;
511de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb0 = (rowA[j] >> 5) & 0x7;
512de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowAb1 = (rowA[k] >> 5) & 0x7;
513de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb0 = (rowB[j] >> 5) & 0x7;
514de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int rowBb1 = (rowB[k] >> 5) & 0x7;
515de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int red = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
516de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
517de779c8d319b6269705cd7e6f2009243a771a2b9Brian         const int blue = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
518de779c8d319b6269705cd7e6f2009243a771a2b9Brian         dst[i] = (blue << 5) | (green << 2) | red;
519de779c8d319b6269705cd7e6f2009243a771a2b9Brian      }
520de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
521de779c8d319b6269705cd7e6f2009243a771a2b9Brian   else {
522de779c8d319b6269705cd7e6f2009243a771a2b9Brian      debug_printf("bad format in do_row()");
523de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
524de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
525de779c8d319b6269705cd7e6f2009243a771a2b9Brian
526de779c8d319b6269705cd7e6f2009243a771a2b9Brian
5279c8db8685432fedd068157795422764ce96b89a0Brian Paul/**
5289c8db8685432fedd068157795422764ce96b89a0Brian Paul * Average together four rows of a source image to produce a single new
5299c8db8685432fedd068157795422764ce96b89a0Brian Paul * row in the dest image.  It's legal for the two source rows to point
5309c8db8685432fedd068157795422764ce96b89a0Brian Paul * to the same data.  The source width must be equal to either the
5319c8db8685432fedd068157795422764ce96b89a0Brian Paul * dest width or two times the dest width.
5329c8db8685432fedd068157795422764ce96b89a0Brian Paul *
5339c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param datatype  GL pixel type \c GL_UNSIGNED_BYTE, \c GL_UNSIGNED_SHORT,
5349c8db8685432fedd068157795422764ce96b89a0Brian Paul *                  \c GL_FLOAT, etc.
5359c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param comps     number of components per pixel (1..4)
5369c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcWidth  Width of a row in the source data
5379c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcRowA   Pointer to one of the rows of source data
5389c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcRowB   Pointer to one of the rows of source data
5399c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcRowC   Pointer to one of the rows of source data
5409c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcRowD   Pointer to one of the rows of source data
5419c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param dstWidth  Width of a row in the destination data
5429c8db8685432fedd068157795422764ce96b89a0Brian Paul * \param srcRowA   Pointer to the row of destination data
5439c8db8685432fedd068157795422764ce96b89a0Brian Paul */
5449c8db8685432fedd068157795422764ce96b89a0Brian Paulstatic void
5459c8db8685432fedd068157795422764ce96b89a0Brian Pauldo_row_3D(enum dtype datatype, uint comps, int srcWidth,
5469c8db8685432fedd068157795422764ce96b89a0Brian Paul          const void *srcRowA, const void *srcRowB,
5479c8db8685432fedd068157795422764ce96b89a0Brian Paul          const void *srcRowC, const void *srcRowD,
5489c8db8685432fedd068157795422764ce96b89a0Brian Paul          int dstWidth, void *dstRow)
5499c8db8685432fedd068157795422764ce96b89a0Brian Paul{
5509c8db8685432fedd068157795422764ce96b89a0Brian Paul   const uint k0 = (srcWidth == dstWidth) ? 0 : 1;
5519c8db8685432fedd068157795422764ce96b89a0Brian Paul   const uint colStride = (srcWidth == dstWidth) ? 1 : 2;
5529c8db8685432fedd068157795422764ce96b89a0Brian Paul   uint i, j, k;
5539c8db8685432fedd068157795422764ce96b89a0Brian Paul
5549c8db8685432fedd068157795422764ce96b89a0Brian Paul   assert(comps >= 1);
5559c8db8685432fedd068157795422764ce96b89a0Brian Paul   assert(comps <= 4);
5569c8db8685432fedd068157795422764ce96b89a0Brian Paul
5570c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   if ((datatype == DTYPE_UBYTE) && (comps == 4)) {
5589c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ubyte, 4);
5599c8db8685432fedd068157795422764ce96b89a0Brian Paul
5609c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
5619c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
5629c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
5639c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
5649c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(2);
5659c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(3);
5669c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
5679c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
5680c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_UBYTE) && (comps == 3)) {
5699c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ubyte, 3);
5709c8db8685432fedd068157795422764ce96b89a0Brian Paul
5719c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
5729c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
5739c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
5749c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
5759c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(2);
5769c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
5779c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
5780c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_UBYTE) && (comps == 2)) {
5799c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ubyte, 2);
5809c8db8685432fedd068157795422764ce96b89a0Brian Paul
5819c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
5829c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
5839c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
5849c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
5859c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
5869c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
5870c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_UBYTE) && (comps == 1)) {
5889c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ubyte, 1);
5899c8db8685432fedd068157795422764ce96b89a0Brian Paul
5909c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
5919c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
5929c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
5939c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
5949c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
5950c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT) && (comps == 4)) {
5969c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ushort, 4);
5979c8db8685432fedd068157795422764ce96b89a0Brian Paul
5989c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
5999c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6009c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
6019c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
6029c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(2);
6039c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(3);
6049c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6059c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6060c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT) && (comps == 3)) {
6079c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ushort, 3);
6089c8db8685432fedd068157795422764ce96b89a0Brian Paul
6099c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6109c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6119c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
6129c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
6139c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(2);
6149c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6159c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6160c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT) && (comps == 2)) {
6179c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ushort, 2);
6189c8db8685432fedd068157795422764ce96b89a0Brian Paul
6199c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6209c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6219c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
6229c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(1);
6239c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6249c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6250c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT) && (comps == 1)) {
6269c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(ushort, 1);
6279c8db8685432fedd068157795422764ce96b89a0Brian Paul
6289c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6299c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6309c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_3D(0);
6319c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6329c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6330c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_FLOAT) && (comps == 4)) {
6349c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(float, 4);
6359c8db8685432fedd068157795422764ce96b89a0Brian Paul
6369c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6379c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6389c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(0);
6399c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(1);
6409c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(2);
6419c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(3);
6429c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6439c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6440c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_FLOAT) && (comps == 3)) {
6459c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(float, 3);
6469c8db8685432fedd068157795422764ce96b89a0Brian Paul
6479c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6489c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6499c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(0);
6509c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(1);
6519c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(2);
6529c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6539c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6540c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_FLOAT) && (comps == 2)) {
6559c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(float, 2);
6569c8db8685432fedd068157795422764ce96b89a0Brian Paul
6579c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6589c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6599c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(0);
6609c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(1);
6619c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6629c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6630c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_FLOAT) && (comps == 1)) {
6649c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(float, 1);
6659c8db8685432fedd068157795422764ce96b89a0Brian Paul
6669c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6679c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6689c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_F_3D(0);
6699c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6709c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6710c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 4)) {
6729c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(half_float, 4);
6739c8db8685432fedd068157795422764ce96b89a0Brian Paul
6749c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6759c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6769c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(0);
6779c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(1);
6789c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(2);
6799c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(3);
6809c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6819c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6820c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 3)) {
6839c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(half_float, 4);
6849c8db8685432fedd068157795422764ce96b89a0Brian Paul
6859c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6869c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6879c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(0);
6889c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(1);
6899c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(2);
6909c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
6919c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
6920c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 2)) {
6939c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(half_float, 4);
6949c8db8685432fedd068157795422764ce96b89a0Brian Paul
6959c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
6969c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
6979c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(0);
6989c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(1);
6999c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
7009c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
7010c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_HALF_FLOAT) && (comps == 1)) {
7029c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS(half_float, 4);
7039c8db8685432fedd068157795422764ce96b89a0Brian Paul
7049c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
7059c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
7069c8db8685432fedd068157795422764ce96b89a0Brian Paul         FILTER_HF_3D(0);
7079c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
7089c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
7090c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_UINT) && (comps == 1)) {
7109c8db8685432fedd068157795422764ce96b89a0Brian Paul      const uint *rowA = (const uint *) srcRowA;
7119c8db8685432fedd068157795422764ce96b89a0Brian Paul      const uint *rowB = (const uint *) srcRowB;
7129c8db8685432fedd068157795422764ce96b89a0Brian Paul      const uint *rowC = (const uint *) srcRowC;
7139c8db8685432fedd068157795422764ce96b89a0Brian Paul      const uint *rowD = (const uint *) srcRowD;
7149c8db8685432fedd068157795422764ce96b89a0Brian Paul      float *dst = (float *) dstRow;
7159c8db8685432fedd068157795422764ce96b89a0Brian Paul
7169c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
7179c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
7189c8db8685432fedd068157795422764ce96b89a0Brian Paul         const uint64_t tmp = (((uint64_t) rowA[j] + (uint64_t) rowA[k])
7199c8db8685432fedd068157795422764ce96b89a0Brian Paul                               + ((uint64_t) rowB[j] + (uint64_t) rowB[k])
7209c8db8685432fedd068157795422764ce96b89a0Brian Paul                               + ((uint64_t) rowC[j] + (uint64_t) rowC[k])
7219c8db8685432fedd068157795422764ce96b89a0Brian Paul                               + ((uint64_t) rowD[j] + (uint64_t) rowD[k]));
7229c8db8685432fedd068157795422764ce96b89a0Brian Paul         dst[i] = (float)((double) tmp * 0.125);
7239c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
7249c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
7250c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT_5_6_5) && (comps == 3)) {
7269c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS0(ushort);
7279c8db8685432fedd068157795422764ce96b89a0Brian Paul
7289c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
7299c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
7309c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr0 = rowA[j] & 0x1f;
7319c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr1 = rowA[k] & 0x1f;
7329c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr0 = rowB[j] & 0x1f;
7339c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr1 = rowB[k] & 0x1f;
7349c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr0 = rowC[j] & 0x1f;
7359c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr1 = rowC[k] & 0x1f;
7369c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr0 = rowD[j] & 0x1f;
7379c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr1 = rowD[k] & 0x1f;
7389c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg0 = (rowA[j] >> 5) & 0x3f;
7399c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg1 = (rowA[k] >> 5) & 0x3f;
7409c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg0 = (rowB[j] >> 5) & 0x3f;
7419c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg1 = (rowB[k] >> 5) & 0x3f;
7429c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg0 = (rowC[j] >> 5) & 0x3f;
7439c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg1 = (rowC[k] >> 5) & 0x3f;
7449c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg0 = (rowD[j] >> 5) & 0x3f;
7459c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg1 = (rowD[k] >> 5) & 0x3f;
7469c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb0 = (rowA[j] >> 11) & 0x1f;
7479c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb1 = (rowA[k] >> 11) & 0x1f;
7489c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb0 = (rowB[j] >> 11) & 0x1f;
7499c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb1 = (rowB[k] >> 11) & 0x1f;
7509c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb0 = (rowC[j] >> 11) & 0x1f;
7519c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb1 = (rowC[k] >> 11) & 0x1f;
7529c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb0 = (rowD[j] >> 11) & 0x1f;
7539c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb1 = (rowD[k] >> 11) & 0x1f;
7549c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
7559c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCr0, rowCr1, rowDr0, rowDr1);
7569c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
7579c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCg0, rowCg1, rowDg0, rowDg1);
7589c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
7599c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCb0, rowCb1, rowDb0, rowDb1);
7609c8db8685432fedd068157795422764ce96b89a0Brian Paul         dst[i] = (b << 11) | (g << 5) | r;
7619c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
7629c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
7630c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT_4_4_4_4) && (comps == 4)) {
7649c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS0(ushort);
7659c8db8685432fedd068157795422764ce96b89a0Brian Paul
7669c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
7679c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
7689c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr0 = rowA[j] & 0xf;
7699c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr1 = rowA[k] & 0xf;
7709c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr0 = rowB[j] & 0xf;
7719c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr1 = rowB[k] & 0xf;
7729c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr0 = rowC[j] & 0xf;
7739c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr1 = rowC[k] & 0xf;
7749c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr0 = rowD[j] & 0xf;
7759c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr1 = rowD[k] & 0xf;
7769c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg0 = (rowA[j] >> 4) & 0xf;
7779c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg1 = (rowA[k] >> 4) & 0xf;
7789c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg0 = (rowB[j] >> 4) & 0xf;
7799c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg1 = (rowB[k] >> 4) & 0xf;
7809c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg0 = (rowC[j] >> 4) & 0xf;
7819c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg1 = (rowC[k] >> 4) & 0xf;
7829c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg0 = (rowD[j] >> 4) & 0xf;
7839c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg1 = (rowD[k] >> 4) & 0xf;
7849c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb0 = (rowA[j] >> 8) & 0xf;
7859c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb1 = (rowA[k] >> 8) & 0xf;
7869c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb0 = (rowB[j] >> 8) & 0xf;
7879c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb1 = (rowB[k] >> 8) & 0xf;
7889c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb0 = (rowC[j] >> 8) & 0xf;
7899c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb1 = (rowC[k] >> 8) & 0xf;
7909c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb0 = (rowD[j] >> 8) & 0xf;
7919c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb1 = (rowD[k] >> 8) & 0xf;
7929c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAa0 = (rowA[j] >> 12) & 0xf;
7939c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAa1 = (rowA[k] >> 12) & 0xf;
7949c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBa0 = (rowB[j] >> 12) & 0xf;
7959c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBa1 = (rowB[k] >> 12) & 0xf;
7969c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCa0 = (rowC[j] >> 12) & 0xf;
7979c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCa1 = (rowC[k] >> 12) & 0xf;
7989c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDa0 = (rowD[j] >> 12) & 0xf;
7999c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDa1 = (rowD[k] >> 12) & 0xf;
8009c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
8019c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCr0, rowCr1, rowDr0, rowDr1);
8029c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
8039c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCg0, rowCg1, rowDg0, rowDg1);
8049c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
8059c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCb0, rowCb1, rowDb0, rowDb1);
8069c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
8079c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCa0, rowCa1, rowDa0, rowDa1);
8089c8db8685432fedd068157795422764ce96b89a0Brian Paul
8099c8db8685432fedd068157795422764ce96b89a0Brian Paul         dst[i] = (a << 12) | (b << 8) | (g << 4) | r;
8109c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
8119c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
8120c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_USHORT_1_5_5_5_REV) && (comps == 4)) {
8139c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS0(ushort);
8149c8db8685432fedd068157795422764ce96b89a0Brian Paul
8159c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
8169c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
8179c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr0 = rowA[j] & 0x1f;
8189c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr1 = rowA[k] & 0x1f;
8199c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr0 = rowB[j] & 0x1f;
8209c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr1 = rowB[k] & 0x1f;
8219c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr0 = rowC[j] & 0x1f;
8229c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr1 = rowC[k] & 0x1f;
8239c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr0 = rowD[j] & 0x1f;
8249c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr1 = rowD[k] & 0x1f;
8259c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg0 = (rowA[j] >> 5) & 0x1f;
8269c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg1 = (rowA[k] >> 5) & 0x1f;
8279c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg0 = (rowB[j] >> 5) & 0x1f;
8289c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg1 = (rowB[k] >> 5) & 0x1f;
8299c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg0 = (rowC[j] >> 5) & 0x1f;
8309c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg1 = (rowC[k] >> 5) & 0x1f;
8319c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg0 = (rowD[j] >> 5) & 0x1f;
8329c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg1 = (rowD[k] >> 5) & 0x1f;
8339c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb0 = (rowA[j] >> 10) & 0x1f;
8349c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb1 = (rowA[k] >> 10) & 0x1f;
8359c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb0 = (rowB[j] >> 10) & 0x1f;
8369c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb1 = (rowB[k] >> 10) & 0x1f;
8379c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb0 = (rowC[j] >> 10) & 0x1f;
8389c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb1 = (rowC[k] >> 10) & 0x1f;
8399c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb0 = (rowD[j] >> 10) & 0x1f;
8409c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb1 = (rowD[k] >> 10) & 0x1f;
8419c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAa0 = (rowA[j] >> 15) & 0x1;
8429c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAa1 = (rowA[k] >> 15) & 0x1;
8439c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBa0 = (rowB[j] >> 15) & 0x1;
8449c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBa1 = (rowB[k] >> 15) & 0x1;
8459c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCa0 = (rowC[j] >> 15) & 0x1;
8469c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCa1 = (rowC[k] >> 15) & 0x1;
8479c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDa0 = (rowD[j] >> 15) & 0x1;
8489c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDa1 = (rowD[k] >> 15) & 0x1;
8499c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
8509c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCr0, rowCr1, rowDr0, rowDr1);
8519c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
8529c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCg0, rowCg1, rowDg0, rowDg1);
8539c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
8549c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCb0, rowCb1, rowDb0, rowDb1);
8559c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int a = FILTER_SUM_3D(rowAa0, rowAa1, rowBa0, rowBa1,
8569c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCa0, rowCa1, rowDa0, rowDa1);
8579c8db8685432fedd068157795422764ce96b89a0Brian Paul
8589c8db8685432fedd068157795422764ce96b89a0Brian Paul         dst[i] = (a << 15) | (b << 10) | (g << 5) | r;
8599c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
8609c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
8610c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell   else if ((datatype == DTYPE_UBYTE_3_3_2) && (comps == 3)) {
8629c8db8685432fedd068157795422764ce96b89a0Brian Paul      DECLARE_ROW_POINTERS0(ushort);
8639c8db8685432fedd068157795422764ce96b89a0Brian Paul
8649c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (i = j = 0, k = k0; i < (uint) dstWidth;
8659c8db8685432fedd068157795422764ce96b89a0Brian Paul           i++, j += colStride, k += colStride) {
8669c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr0 = rowA[j] & 0x3;
8679c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAr1 = rowA[k] & 0x3;
8689c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr0 = rowB[j] & 0x3;
8699c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBr1 = rowB[k] & 0x3;
8709c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr0 = rowC[j] & 0x3;
8719c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCr1 = rowC[k] & 0x3;
8729c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr0 = rowD[j] & 0x3;
8739c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDr1 = rowD[k] & 0x3;
8749c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg0 = (rowA[j] >> 2) & 0x7;
8759c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAg1 = (rowA[k] >> 2) & 0x7;
8769c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg0 = (rowB[j] >> 2) & 0x7;
8779c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBg1 = (rowB[k] >> 2) & 0x7;
8789c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg0 = (rowC[j] >> 2) & 0x7;
8799c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCg1 = (rowC[k] >> 2) & 0x7;
8809c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg0 = (rowD[j] >> 2) & 0x7;
8819c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDg1 = (rowD[k] >> 2) & 0x7;
8829c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb0 = (rowA[j] >> 5) & 0x7;
8839c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowAb1 = (rowA[k] >> 5) & 0x7;
8849c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb0 = (rowB[j] >> 5) & 0x7;
8859c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowBb1 = (rowB[k] >> 5) & 0x7;
8869c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb0 = (rowC[j] >> 5) & 0x7;
8879c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowCb1 = (rowC[k] >> 5) & 0x7;
8889c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb0 = (rowD[j] >> 5) & 0x7;
8899c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int rowDb1 = (rowD[k] >> 5) & 0x7;
8909c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int r = FILTER_SUM_3D(rowAr0, rowAr1, rowBr0, rowBr1,
8919c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCr0, rowCr1, rowDr0, rowDr1);
8929c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int g = FILTER_SUM_3D(rowAg0, rowAg1, rowBg0, rowBg1,
8939c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCg0, rowCg1, rowDg0, rowDg1);
8949c8db8685432fedd068157795422764ce96b89a0Brian Paul         const int b = FILTER_SUM_3D(rowAb0, rowAb1, rowBb0, rowBb1,
8959c8db8685432fedd068157795422764ce96b89a0Brian Paul                                       rowCb0, rowCb1, rowDb0, rowDb1);
8969c8db8685432fedd068157795422764ce96b89a0Brian Paul         dst[i] = (b << 5) | (g << 2) | r;
8979c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
8989c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
8999c8db8685432fedd068157795422764ce96b89a0Brian Paul   else {
9009c8db8685432fedd068157795422764ce96b89a0Brian Paul      debug_printf("bad format in do_row_3D()");
9019c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
9029c8db8685432fedd068157795422764ce96b89a0Brian Paul}
9039c8db8685432fedd068157795422764ce96b89a0Brian Paul
9049c8db8685432fedd068157795422764ce96b89a0Brian Paul
9059c8db8685432fedd068157795422764ce96b89a0Brian Paul
906de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
907de779c8d319b6269705cd7e6f2009243a771a2b9Brianformat_to_type_comps(enum pipe_format pformat,
908de779c8d319b6269705cd7e6f2009243a771a2b9Brian                     enum dtype *datatype, uint *comps)
909de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
910f8ae968d2898352cd4ac649fff0ea19ac42f56b4Brian Paul   /* XXX I think this could be implemented in terms of the pf_*() functions */
911de779c8d319b6269705cd7e6f2009243a771a2b9Brian   switch (pformat) {
912de779c8d319b6269705cd7e6f2009243a771a2b9Brian   case PIPE_FORMAT_B8G8R8A8_UNORM:
9137333578d2a5fa18f7f0101fc3fd3b03cf2f356bcMichel Dänzer   case PIPE_FORMAT_B8G8R8X8_UNORM:
914712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_A8R8G8B8_UNORM:
915712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_X8R8G8B8_UNORM:
916712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_A8B8G8R8_SRGB:
917712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_X8B8G8R8_SRGB:
918f8ae968d2898352cd4ac649fff0ea19ac42f56b4Brian Paul   case PIPE_FORMAT_B8G8R8A8_SRGB:
919f8ae968d2898352cd4ac649fff0ea19ac42f56b4Brian Paul   case PIPE_FORMAT_B8G8R8X8_SRGB:
920712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_A8R8G8B8_SRGB:
921712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_X8R8G8B8_SRGB:
922f8ae968d2898352cd4ac649fff0ea19ac42f56b4Brian Paul   case PIPE_FORMAT_R8G8B8_SRGB:
9230c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_UBYTE;
924de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 4;
925de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
92694abc4b51e134bee1ace2b57400e35c295bda6f8Alan Hourihane   case PIPE_FORMAT_B5G5R5X1_UNORM:
927712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_B5G5R5A1_UNORM:
9280c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_USHORT_1_5_5_5_REV;
929de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 4;
930de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
931712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_B4G4R4A4_UNORM:
9320c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_USHORT_4_4_4_4;
933de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 4;
934de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
935712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_B5G6R5_UNORM:
9360c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_USHORT_5_6_5;
937de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 3;
938de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
93954f94a790e4488445347abcff9a636a9c440d7f9Brian Paul   case PIPE_FORMAT_L8_UNORM:
940f8ae968d2898352cd4ac649fff0ea19ac42f56b4Brian Paul   case PIPE_FORMAT_L8_SRGB:
94154f94a790e4488445347abcff9a636a9c440d7f9Brian Paul   case PIPE_FORMAT_A8_UNORM:
94254f94a790e4488445347abcff9a636a9c440d7f9Brian Paul   case PIPE_FORMAT_I8_UNORM:
9430c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_UBYTE;
944de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 1;
945de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
946712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_L8A8_UNORM:
947712ba6e6b049c050af3ac1992aba009ebbe56ca5José Fonseca   case PIPE_FORMAT_L8A8_SRGB:
9480c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_UBYTE;
949de779c8d319b6269705cd7e6f2009243a771a2b9Brian      *comps = 2;
950de779c8d319b6269705cd7e6f2009243a771a2b9Brian      return;
951de779c8d319b6269705cd7e6f2009243a771a2b9Brian   default:
952de779c8d319b6269705cd7e6f2009243a771a2b9Brian      assert(0);
9530c550b0425409c6cfa745257dc12e9758d9b3df0Keith Whitwell      *datatype = DTYPE_UBYTE;
95435b0efb8c6afd319ae36e99aa578ac6c75faf2f5Keith Whitwell      *comps = 0;
95535b0efb8c6afd319ae36e99aa578ac6c75faf2f5Keith Whitwell      break;
956de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
957de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
958de779c8d319b6269705cd7e6f2009243a771a2b9Brian
959de779c8d319b6269705cd7e6f2009243a771a2b9Brian
960de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
961de779c8d319b6269705cd7e6f2009243a771a2b9Brianreduce_1d(enum pipe_format pformat,
962de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int srcWidth, const ubyte *srcPtr,
963de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int dstWidth, ubyte *dstPtr)
964de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
965de779c8d319b6269705cd7e6f2009243a771a2b9Brian   enum dtype datatype;
966de779c8d319b6269705cd7e6f2009243a771a2b9Brian   uint comps;
967de779c8d319b6269705cd7e6f2009243a771a2b9Brian
968de779c8d319b6269705cd7e6f2009243a771a2b9Brian   format_to_type_comps(pformat, &datatype, &comps);
969de779c8d319b6269705cd7e6f2009243a771a2b9Brian
970de779c8d319b6269705cd7e6f2009243a771a2b9Brian   /* we just duplicate the input row, kind of hack, saves code */
971de779c8d319b6269705cd7e6f2009243a771a2b9Brian   do_row(datatype, comps,
972de779c8d319b6269705cd7e6f2009243a771a2b9Brian          srcWidth, srcPtr, srcPtr,
973de779c8d319b6269705cd7e6f2009243a771a2b9Brian          dstWidth, dstPtr);
974de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
975de779c8d319b6269705cd7e6f2009243a771a2b9Brian
976de779c8d319b6269705cd7e6f2009243a771a2b9Brian
977de779c8d319b6269705cd7e6f2009243a771a2b9Brian/**
978de779c8d319b6269705cd7e6f2009243a771a2b9Brian * Strides are in bytes.  If zero, it'll be computed as width * bpp.
979de779c8d319b6269705cd7e6f2009243a771a2b9Brian */
980de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
981de779c8d319b6269705cd7e6f2009243a771a2b9Brianreduce_2d(enum pipe_format pformat,
982de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int srcWidth, int srcHeight,
983de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int srcRowStride, const ubyte *srcPtr,
984de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int dstWidth, int dstHeight,
985de779c8d319b6269705cd7e6f2009243a771a2b9Brian          int dstRowStride, ubyte *dstPtr)
986de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
987de779c8d319b6269705cd7e6f2009243a771a2b9Brian   enum dtype datatype;
988de779c8d319b6269705cd7e6f2009243a771a2b9Brian   uint comps;
989b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   const int bpt = util_format_get_blocksize(pformat);
990de779c8d319b6269705cd7e6f2009243a771a2b9Brian   const ubyte *srcA, *srcB;
991de779c8d319b6269705cd7e6f2009243a771a2b9Brian   ubyte *dst;
992de779c8d319b6269705cd7e6f2009243a771a2b9Brian   int row;
993de779c8d319b6269705cd7e6f2009243a771a2b9Brian
994de779c8d319b6269705cd7e6f2009243a771a2b9Brian   format_to_type_comps(pformat, &datatype, &comps);
995de779c8d319b6269705cd7e6f2009243a771a2b9Brian
996de779c8d319b6269705cd7e6f2009243a771a2b9Brian   if (!srcRowStride)
997de779c8d319b6269705cd7e6f2009243a771a2b9Brian      srcRowStride = bpt * srcWidth;
998de779c8d319b6269705cd7e6f2009243a771a2b9Brian
999de779c8d319b6269705cd7e6f2009243a771a2b9Brian   if (!dstRowStride)
1000de779c8d319b6269705cd7e6f2009243a771a2b9Brian      dstRowStride = bpt * dstWidth;
1001de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1002de779c8d319b6269705cd7e6f2009243a771a2b9Brian   /* Compute src and dst pointers */
1003de779c8d319b6269705cd7e6f2009243a771a2b9Brian   srcA = srcPtr;
1004de779c8d319b6269705cd7e6f2009243a771a2b9Brian   if (srcHeight > 1)
1005de779c8d319b6269705cd7e6f2009243a771a2b9Brian      srcB = srcA + srcRowStride;
1006de779c8d319b6269705cd7e6f2009243a771a2b9Brian   else
1007de779c8d319b6269705cd7e6f2009243a771a2b9Brian      srcB = srcA;
1008de779c8d319b6269705cd7e6f2009243a771a2b9Brian   dst = dstPtr;
1009de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1010de779c8d319b6269705cd7e6f2009243a771a2b9Brian   for (row = 0; row < dstHeight; row++) {
1011de779c8d319b6269705cd7e6f2009243a771a2b9Brian      do_row(datatype, comps,
1012de779c8d319b6269705cd7e6f2009243a771a2b9Brian             srcWidth, srcA, srcB,
1013de779c8d319b6269705cd7e6f2009243a771a2b9Brian             dstWidth, dst);
1014de779c8d319b6269705cd7e6f2009243a771a2b9Brian      srcA += 2 * srcRowStride;
1015de779c8d319b6269705cd7e6f2009243a771a2b9Brian      srcB += 2 * srcRowStride;
1016de779c8d319b6269705cd7e6f2009243a771a2b9Brian      dst += dstRowStride;
1017de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
1018de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
1019de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1020de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1021de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
10229c8db8685432fedd068157795422764ce96b89a0Brian Paulreduce_3d(enum pipe_format pformat,
10239c8db8685432fedd068157795422764ce96b89a0Brian Paul          int srcWidth, int srcHeight, int srcDepth,
10244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          int srcRowStride, int srcImageStride, const ubyte *srcPtr,
10259c8db8685432fedd068157795422764ce96b89a0Brian Paul          int dstWidth, int dstHeight, int dstDepth,
10264c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          int dstRowStride, int dstImageStride, ubyte *dstPtr)
10279c8db8685432fedd068157795422764ce96b89a0Brian Paul{
1028b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   const int bpt = util_format_get_blocksize(pformat);
10299c8db8685432fedd068157795422764ce96b89a0Brian Paul   int img, row;
10309c8db8685432fedd068157795422764ce96b89a0Brian Paul   int srcImageOffset, srcRowOffset;
10319c8db8685432fedd068157795422764ce96b89a0Brian Paul   enum dtype datatype;
10329c8db8685432fedd068157795422764ce96b89a0Brian Paul   uint comps;
10339c8db8685432fedd068157795422764ce96b89a0Brian Paul
10349c8db8685432fedd068157795422764ce96b89a0Brian Paul   format_to_type_comps(pformat, &datatype, &comps);
10359c8db8685432fedd068157795422764ce96b89a0Brian Paul
10364c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   /* XXX I think we should rather assert those strides */
10374c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   if (!srcImageStride)
10384c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      srcImageStride = srcWidth * srcHeight * bpt;
10394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   if (!dstImageStride)
10404c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dstImageStride = dstWidth * dstHeight * bpt;
10419c8db8685432fedd068157795422764ce96b89a0Brian Paul
10424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   if (!srcRowStride)
10434c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      srcRowStride = srcWidth * bpt;
10444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   if (!dstRowStride)
10454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dstRowStride = dstWidth * bpt;
10469c8db8685432fedd068157795422764ce96b89a0Brian Paul
10479c8db8685432fedd068157795422764ce96b89a0Brian Paul   /* Offset between adjacent src images to be averaged together */
10484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   srcImageOffset = (srcDepth == dstDepth) ? 0 : srcImageStride;
10499c8db8685432fedd068157795422764ce96b89a0Brian Paul
10509c8db8685432fedd068157795422764ce96b89a0Brian Paul   /* Offset between adjacent src rows to be averaged together */
10514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcRowStride;
10529c8db8685432fedd068157795422764ce96b89a0Brian Paul
10539c8db8685432fedd068157795422764ce96b89a0Brian Paul   /*
10549c8db8685432fedd068157795422764ce96b89a0Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
10559c8db8685432fedd068157795422764ce96b89a0Brian Paul    * Break that down into 3 operations:
10569c8db8685432fedd068157795422764ce96b89a0Brian Paul    *   1. take two rows from source image and average them together.
10579c8db8685432fedd068157795422764ce96b89a0Brian Paul    *   2. take two rows from next source image and average them together.
10589c8db8685432fedd068157795422764ce96b89a0Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
10599c8db8685432fedd068157795422764ce96b89a0Brian Paul    */
10609c8db8685432fedd068157795422764ce96b89a0Brian Paul
10619c8db8685432fedd068157795422764ce96b89a0Brian Paul   /*
1062298be2b028263b2c343a707662c6fbfa18293cb2Kristian Høgsberg   printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
10639c8db8685432fedd068157795422764ce96b89a0Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
10649c8db8685432fedd068157795422764ce96b89a0Brian Paul   */
10659c8db8685432fedd068157795422764ce96b89a0Brian Paul
10669c8db8685432fedd068157795422764ce96b89a0Brian Paul   for (img = 0; img < dstDepth; img++) {
10674c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      /* first source image pointer */
10689c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *imgSrcA = srcPtr
10694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         + img * (srcImageStride + srcImageOffset);
10704c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      /* second source image pointer */
10719c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *imgSrcB = imgSrcA + srcImageOffset;
10724c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      /* address of the dest image */
10734fc62a074c5cc7e55a81c2a24cc5ef2f1452e948Brian Paul      ubyte *imgDst = dstPtr + img * dstImageStride;
10749c8db8685432fedd068157795422764ce96b89a0Brian Paul
10759c8db8685432fedd068157795422764ce96b89a0Brian Paul      /* setup the four source row pointers and the dest row pointer */
10769c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *srcImgARowA = imgSrcA;
10779c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *srcImgARowB = imgSrcA + srcRowOffset;
10789c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *srcImgBRowA = imgSrcB;
10799c8db8685432fedd068157795422764ce96b89a0Brian Paul      const ubyte *srcImgBRowB = imgSrcB + srcRowOffset;
10809c8db8685432fedd068157795422764ce96b89a0Brian Paul      ubyte *dstImgRow = imgDst;
10819c8db8685432fedd068157795422764ce96b89a0Brian Paul
10829c8db8685432fedd068157795422764ce96b89a0Brian Paul      for (row = 0; row < dstHeight; row++) {
10839c8db8685432fedd068157795422764ce96b89a0Brian Paul         do_row_3D(datatype, comps, srcWidth,
10849c8db8685432fedd068157795422764ce96b89a0Brian Paul                   srcImgARowA, srcImgARowB,
10859c8db8685432fedd068157795422764ce96b89a0Brian Paul                   srcImgBRowA, srcImgBRowB,
10869c8db8685432fedd068157795422764ce96b89a0Brian Paul                   dstWidth, dstImgRow);
10879c8db8685432fedd068157795422764ce96b89a0Brian Paul
10889c8db8685432fedd068157795422764ce96b89a0Brian Paul         /* advance to next rows */
10894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         srcImgARowA += srcRowStride + srcRowOffset;
10904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         srcImgARowB += srcRowStride + srcRowOffset;
10914c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         srcImgBRowA += srcRowStride + srcRowOffset;
10924c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         srcImgBRowB += srcRowStride + srcRowOffset;
10934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         dstImgRow += dstImageStride;
10949c8db8685432fedd068157795422764ce96b89a0Brian Paul      }
10959c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
10969c8db8685432fedd068157795422764ce96b89a0Brian Paul}
10979c8db8685432fedd068157795422764ce96b89a0Brian Paul
10989c8db8685432fedd068157795422764ce96b89a0Brian Paul
10999c8db8685432fedd068157795422764ce96b89a0Brian Paul
11009c8db8685432fedd068157795422764ce96b89a0Brian Paul
11019c8db8685432fedd068157795422764ce96b89a0Brian Paulstatic void
1102de779c8d319b6269705cd7e6f2009243a771a2b9Brianmake_1d_mipmap(struct gen_mipmap_state *ctx,
1103287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell               struct pipe_resource *pt,
11044c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger               uint layer, uint baseLevel, uint lastLevel)
1105de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
1106de779c8d319b6269705cd7e6f2009243a771a2b9Brian   struct pipe_context *pipe = ctx->pipe;
1107de779c8d319b6269705cd7e6f2009243a771a2b9Brian   uint dstLevel;
1108de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1109de779c8d319b6269705cd7e6f2009243a771a2b9Brian   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
1110de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const uint srcLevel = dstLevel - 1;
11114617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      struct pipe_transfer *srcTrans, *dstTrans;
1112de779c8d319b6269705cd7e6f2009243a771a2b9Brian      void *srcMap, *dstMap;
11134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
11144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
11154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   PIPE_TRANSFER_READ, 0, 0,
11164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->width0, srcLevel),
11174c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->height0, srcLevel));
11184c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
11194c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   PIPE_TRANSFER_WRITE, 0, 0,
11204c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->width0, dstLevel),
11214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->height0, dstLevel));
11224617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer
1123b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
1124b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
1125de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1126de779c8d319b6269705cd7e6f2009243a771a2b9Brian      reduce_1d(pt->format,
1127287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                srcTrans->box.width, srcMap,
1128287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                dstTrans->box.width, dstMap);
1129de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1130b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, srcTrans);
1131b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, dstTrans);
1132de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1133287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, srcTrans);
1134287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, dstTrans);
1135de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
1136de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
1137de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1138de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1139de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
1140de779c8d319b6269705cd7e6f2009243a771a2b9Brianmake_2d_mipmap(struct gen_mipmap_state *ctx,
1141287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell               struct pipe_resource *pt,
11424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger               uint layer, uint baseLevel, uint lastLevel)
1143de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
1144de779c8d319b6269705cd7e6f2009243a771a2b9Brian   struct pipe_context *pipe = ctx->pipe;
1145de779c8d319b6269705cd7e6f2009243a771a2b9Brian   uint dstLevel;
11464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
1147b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   assert(util_format_get_blockwidth(pt->format) == 1);
1148b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   assert(util_format_get_blockheight(pt->format) == 1);
1149de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1150de779c8d319b6269705cd7e6f2009243a771a2b9Brian   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
1151de779c8d319b6269705cd7e6f2009243a771a2b9Brian      const uint srcLevel = dstLevel - 1;
11524617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      struct pipe_transfer *srcTrans, *dstTrans;
1153de779c8d319b6269705cd7e6f2009243a771a2b9Brian      ubyte *srcMap, *dstMap;
11544c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
11554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      srcTrans = pipe_get_transfer(pipe, pt, srcLevel, layer,
11564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   PIPE_TRANSFER_READ, 0, 0,
11574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->width0, srcLevel),
11584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->height0, srcLevel));
11594c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dstTrans = pipe_get_transfer(pipe, pt, dstLevel, layer,
11604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   PIPE_TRANSFER_WRITE, 0, 0,
11614c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->width0, dstLevel),
11624c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                   u_minify(pt->height0, dstLevel));
11634617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer
1164b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
1165b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
1166de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1167de779c8d319b6269705cd7e6f2009243a771a2b9Brian      reduce_2d(pt->format,
1168287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                srcTrans->box.width, srcTrans->box.height,
11694617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                srcTrans->stride, srcMap,
1170287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                dstTrans->box.width, dstTrans->box.height,
11714617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer                dstTrans->stride, dstMap);
1172de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1173b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, srcTrans);
1174b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, dstTrans);
1175de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1176287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, srcTrans);
1177287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, dstTrans);
1178de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
1179de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
1180de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1181de779c8d319b6269705cd7e6f2009243a771a2b9Brian
11824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger/* XXX looks a bit more like it could work now but need to test */
1183de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
1184de779c8d319b6269705cd7e6f2009243a771a2b9Brianmake_3d_mipmap(struct gen_mipmap_state *ctx,
1185287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell               struct pipe_resource *pt,
1186de779c8d319b6269705cd7e6f2009243a771a2b9Brian               uint face, uint baseLevel, uint lastLevel)
1187de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
11889c8db8685432fedd068157795422764ce96b89a0Brian Paul   struct pipe_context *pipe = ctx->pipe;
11894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   uint dstLevel;
11904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   struct pipe_box src_box, dst_box;
11919c8db8685432fedd068157795422764ce96b89a0Brian Paul
1192b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   assert(util_format_get_blockwidth(pt->format) == 1);
1193b1ed72ebe2599ec178f51d86fd42f26486b9a19bMichal Krol   assert(util_format_get_blockheight(pt->format) == 1);
11949c8db8685432fedd068157795422764ce96b89a0Brian Paul
11954c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   src_box.x = src_box.y = src_box.z = 0;
11964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   dst_box.x = dst_box.y = dst_box.z = 0;
11974c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
11989c8db8685432fedd068157795422764ce96b89a0Brian Paul   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
11999c8db8685432fedd068157795422764ce96b89a0Brian Paul      const uint srcLevel = dstLevel - 1;
12004617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer      struct pipe_transfer *srcTrans, *dstTrans;
12019c8db8685432fedd068157795422764ce96b89a0Brian Paul      ubyte *srcMap, *dstMap;
12024c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      struct pipe_box src_box, dst_box;
12034c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      src_box.width = u_minify(pt->width0, srcLevel);
12044c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      src_box.height = u_minify(pt->height0, srcLevel);
12054c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      src_box.depth = u_minify(pt->depth0, srcLevel);
12064c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dst_box.width = u_minify(pt->width0, dstLevel);
12074c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dst_box.height = u_minify(pt->height0, dstLevel);
12084c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dst_box.depth = u_minify(pt->depth0, dstLevel);
12094c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
12104c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      srcTrans = pipe->get_transfer(pipe, pt, srcLevel,
12114c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    PIPE_TRANSFER_READ,
12124c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    &src_box);
12134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      dstTrans = pipe->get_transfer(pipe, pt, dstLevel,
12144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    PIPE_TRANSFER_WRITE,
12154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                    &dst_box);
12164617981ec72f7985941bee4b03c534d97ff96bc6Michel Dänzer
1217b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      srcMap = (ubyte *) pipe->transfer_map(pipe, srcTrans);
1218b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      dstMap = (ubyte *) pipe->transfer_map(pipe, dstTrans);
12199c8db8685432fedd068157795422764ce96b89a0Brian Paul
12209c8db8685432fedd068157795422764ce96b89a0Brian Paul      reduce_3d(pt->format,
12214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                srcTrans->box.width, srcTrans->box.height, srcTrans->box.depth,
12224c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                srcTrans->stride, srcTrans->layer_stride, srcMap,
12234c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                dstTrans->box.width, dstTrans->box.height, dstTrans->box.depth,
12244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                dstTrans->stride, dstTrans->layer_stride, dstMap);
12259c8db8685432fedd068157795422764ce96b89a0Brian Paul
1226b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, srcTrans);
1227b43c182f19c6291c88420fa12714f952c2b461fbKeith Whitwell      pipe->transfer_unmap(pipe, dstTrans);
12289c8db8685432fedd068157795422764ce96b89a0Brian Paul
1229287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, srcTrans);
1230287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell      pipe->transfer_destroy(pipe, dstTrans);
12319c8db8685432fedd068157795422764ce96b89a0Brian Paul   }
1232de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
1233de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1234de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1235de779c8d319b6269705cd7e6f2009243a771a2b9Brianstatic void
1236de779c8d319b6269705cd7e6f2009243a771a2b9Brianfallback_gen_mipmap(struct gen_mipmap_state *ctx,
1237287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                    struct pipe_resource *pt,
12384c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                    uint layer, uint baseLevel, uint lastLevel)
1239de779c8d319b6269705cd7e6f2009243a771a2b9Brian{
1240de779c8d319b6269705cd7e6f2009243a771a2b9Brian   switch (pt->target) {
1241de779c8d319b6269705cd7e6f2009243a771a2b9Brian   case PIPE_TEXTURE_1D:
12424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      make_1d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
1243de779c8d319b6269705cd7e6f2009243a771a2b9Brian      break;
1244de779c8d319b6269705cd7e6f2009243a771a2b9Brian   case PIPE_TEXTURE_2D:
1245ae0ef6f69f351cacdc7eaa9b21097a7c1b414e44Luca Barbieri   case PIPE_TEXTURE_RECT:
1246de779c8d319b6269705cd7e6f2009243a771a2b9Brian   case PIPE_TEXTURE_CUBE:
12474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      make_2d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
1248de779c8d319b6269705cd7e6f2009243a771a2b9Brian      break;
1249de779c8d319b6269705cd7e6f2009243a771a2b9Brian   case PIPE_TEXTURE_3D:
12504c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      make_3d_mipmap(ctx, pt, layer, baseLevel, lastLevel);
1251de779c8d319b6269705cd7e6f2009243a771a2b9Brian      break;
1252de779c8d319b6269705cd7e6f2009243a771a2b9Brian   default:
1253de779c8d319b6269705cd7e6f2009243a771a2b9Brian      assert(0);
1254de779c8d319b6269705cd7e6f2009243a771a2b9Brian   }
1255de779c8d319b6269705cd7e6f2009243a771a2b9Brian}
1256de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1257de779c8d319b6269705cd7e6f2009243a771a2b9Brian
1258f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian/**
1259f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Create a mipmap generation context.
1260f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * The idea is to create one of these and re-use it each time we need to
1261f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * generate a mipmap.
1262f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian */
1263f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrianstruct gen_mipmap_state *
12647d95efde0a0e13e13c59444703bc47eb13926385Brianutil_create_gen_mipmap(struct pipe_context *pipe,
12657d95efde0a0e13e13c59444703bc47eb13926385Brian                       struct cso_context *cso)
1266f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian{
1267f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   struct gen_mipmap_state *ctx;
1268309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian   uint i;
1269f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1270f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   ctx = CALLOC_STRUCT(gen_mipmap_state);
1271f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   if (!ctx)
1272f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian      return NULL;
1273f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1274f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   ctx->pipe = pipe;
12757d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->cso = cso;
1276f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
12777d95efde0a0e13e13c59444703bc47eb13926385Brian   /* disabled blending/masking */
127891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   memset(&ctx->blend_keep_color, 0, sizeof(ctx->blend_keep_color));
127991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   memset(&ctx->blend_write_color, 0, sizeof(ctx->blend_write_color));
128091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   ctx->blend_write_color.rt[0].colormask = PIPE_MASK_RGBA;
1281f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
12827d95efde0a0e13e13c59444703bc47eb13926385Brian   /* no-op depth/stencil/alpha */
128391cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   memset(&ctx->dsa_keep_depth, 0, sizeof(ctx->dsa_keep_depth));
128491cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   memset(&ctx->dsa_write_depth, 0, sizeof(ctx->dsa_write_depth));
128591cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   ctx->dsa_write_depth.depth.enabled = 1;
128691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   ctx->dsa_write_depth.depth.func = PIPE_FUNC_ALWAYS;
128791cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   ctx->dsa_write_depth.depth.writemask = 1;
1288f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1289f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   /* rasterizer */
12907d95efde0a0e13e13c59444703bc47eb13926385Brian   memset(&ctx->rasterizer, 0, sizeof(ctx->rasterizer));
12910bd1cbcd0d28dbadfb0c3e1f8b048a18b56bc72cKeith Whitwell   ctx->rasterizer.cull_face = PIPE_FACE_NONE;
12926afab9001e5ebe5a970810b0e12dbfac0d9abe14Brian Paul   ctx->rasterizer.gl_rasterization_rules = 1;
1293dc4c821f0817a3db716f965692fb701079f66340Marek Olšák   ctx->rasterizer.depth_clip = 1;
12947d95efde0a0e13e13c59444703bc47eb13926385Brian
12957d95efde0a0e13e13c59444703bc47eb13926385Brian   /* sampler state */
12967d95efde0a0e13e13c59444703bc47eb13926385Brian   memset(&ctx->sampler, 0, sizeof(ctx->sampler));
12977d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
12987d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
12997d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
13007d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NEAREST;
13017d95efde0a0e13e13c59444703bc47eb13926385Brian   ctx->sampler.normalized_coords = 1;
13027d95efde0a0e13e13c59444703bc47eb13926385Brian
1303ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   /* vertex elements state */
1304ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   memset(&ctx->velem[0], 0, sizeof(ctx->velem[0]) * 2);
1305ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   for (i = 0; i < 2; i++) {
1306ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger      ctx->velem[i].src_offset = i * 4 * sizeof(float);
1307ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger      ctx->velem[i].instance_divisor = 0;
1308ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger      ctx->velem[i].vertex_buffer_index = 0;
1309ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger      ctx->velem[i].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
1310ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   }
1311ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger
1312309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian   /* vertex data that doesn't change */
1313309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian   for (i = 0; i < 4; i++) {
1314309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian      ctx->vertices[i][0][2] = 0.0f; /* z */
1315309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian      ctx->vertices[i][0][3] = 1.0f; /* w */
1316309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian      ctx->vertices[i][1][3] = 1.0f; /* q */
1317309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian   }
1318309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1319d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul   /* Note: the actual vertex buffer is allocated as needed below */
1320d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul
1321f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   return ctx;
1322f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian}
1323f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1324f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1325d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul/**
13261a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz * Helper function to set the fragment shaders.
13271a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz */
13281a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantzstatic INLINE void
132991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšákset_fragment_shader(struct gen_mipmap_state *ctx, uint type,
133091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                    boolean output_depth)
13311a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz{
133291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   if (output_depth) {
133391cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      if (!ctx->fs_depth[type])
133491cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         ctx->fs_depth[type] =
133591cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            util_make_fragment_tex_shader_writedepth(ctx->pipe, type,
133691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                                     TGSI_INTERPOLATE_LINEAR);
13371a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
133891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_depth[type]);
133991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   }
134091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   else {
134191cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      if (!ctx->fs_color[type])
134291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         ctx->fs_color[type] =
134391cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            util_make_fragment_tex_shader(ctx->pipe, type,
134491cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                          TGSI_INTERPOLATE_LINEAR);
134591cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák
134691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      cso_set_fragment_shader_handle(ctx->cso, ctx->fs_color[type]);
134791cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   }
13481a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz}
13491a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
13501a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
13511a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz/**
13521a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz * Helper function to set the vertex shader.
13531a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz */
13541a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantzstatic INLINE void
13551a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantzset_vertex_shader(struct gen_mipmap_state *ctx)
13561a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz{
13571a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   /* vertex shader - still required to provide the linkage between
13581a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz    * fragment shader input semantics and vertex_element/buffers.
13591a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz    */
13601a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   if (!ctx->vs)
13611a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   {
13621a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      const uint semantic_names[] = { TGSI_SEMANTIC_POSITION,
13631a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz                                      TGSI_SEMANTIC_GENERIC };
13641a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      const uint semantic_indexes[] = { 0, 0 };
13651a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      ctx->vs = util_make_vertex_passthrough_shader(ctx->pipe, 2,
13661a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz                                                    semantic_names,
13671a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz                                                    semantic_indexes);
13681a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   }
13691a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
13701a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
13711a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz}
13721a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
13731a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
13741a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz/**
1375d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul * Get next "slot" of vertex space in the vertex buffer.
1376d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul * We're allocating one large vertex buffer and using it piece by piece.
1377d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul */
1378d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paulstatic unsigned
1379d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paulget_next_slot(struct gen_mipmap_state *ctx)
1380d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell{
1381d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   const unsigned max_slots = 4096 / sizeof ctx->vertices;
1382d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1383bdb0ad77c20653d01570a4ce44f4200a97fb5f11Marek Olšák   if (ctx->vbuf_slot >= max_slots) {
1384bdb0ad77c20653d01570a4ce44f4200a97fb5f11Marek Olšák      pipe_resource_reference(&ctx->vbuf, NULL);
1385bdb0ad77c20653d01570a4ce44f4200a97fb5f11Marek Olšák      ctx->vbuf_slot = 0;
1386bdb0ad77c20653d01570a4ce44f4200a97fb5f11Marek Olšák   }
1387d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1388d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   if (!ctx->vbuf) {
1389d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell      ctx->vbuf = pipe_buffer_create(ctx->pipe->screen,
1390287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell                                     PIPE_BIND_VERTEX_BUFFER,
1391eafb7f234d11a290b00dcaf5492b9bdad1cf5148Marek Olšák                                     PIPE_USAGE_STREAM,
1392d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell                                     max_slots * sizeof ctx->vertices);
1393d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   }
1394d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1395d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   return ctx->vbuf_slot++ * sizeof ctx->vertices;
1396d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell}
1397d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1398d1c8af7c0a18340fdde45ade6f612939a3c8e62aBrian Paul
1399d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwellstatic unsigned
140079ada8c6331a801a0475f38a540670b14e168f19Brian Paulset_vertex_data(struct gen_mipmap_state *ctx,
140179ada8c6331a801a0475f38a540670b14e168f19Brian Paul                enum pipe_texture_target tex_target,
14024c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                uint layer, float r)
1403309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian{
1404d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   unsigned offset;
1405309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
140679ada8c6331a801a0475f38a540670b14e168f19Brian Paul   /* vert[0].position */
140763cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[0][0][0] = -1.0f; /*x*/
140863cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[0][0][1] = -1.0f; /*y*/
1409309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
141079ada8c6331a801a0475f38a540670b14e168f19Brian Paul   /* vert[1].position */
141163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[1][0][0] = 1.0f;
141263cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[1][0][1] = -1.0f;
1413309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
141479ada8c6331a801a0475f38a540670b14e168f19Brian Paul   /* vert[2].position */
141563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[2][0][0] = 1.0f;
141663cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[2][0][1] = 1.0f;
1417309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
141879ada8c6331a801a0475f38a540670b14e168f19Brian Paul   /* vert[3].position */
141963cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[3][0][0] = -1.0f;
142063cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   ctx->vertices[3][0][1] = 1.0f;
142179ada8c6331a801a0475f38a540670b14e168f19Brian Paul
142279ada8c6331a801a0475f38a540670b14e168f19Brian Paul   /* Setup vertex texcoords.  This is a little tricky for cube maps. */
142379ada8c6331a801a0475f38a540670b14e168f19Brian Paul   if (tex_target == PIPE_TEXTURE_CUBE) {
142479ada8c6331a801a0475f38a540670b14e168f19Brian Paul      static const float st[4][2] = {
142579ada8c6331a801a0475f38a540670b14e168f19Brian Paul         {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
142679ada8c6331a801a0475f38a540670b14e168f19Brian Paul      };
142779ada8c6331a801a0475f38a540670b14e168f19Brian Paul
14284c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      util_map_texcoords2d_onto_cubemap(layer, &st[0][0], 2,
14294c61022b4a19f020ef8f6c635ecffa54a914fd7aMarek Olšák                                        &ctx->vertices[0][1][0], 8);
143079ada8c6331a801a0475f38a540670b14e168f19Brian Paul   }
1431179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie   else if (tex_target == PIPE_TEXTURE_1D_ARRAY) {
1432179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      /* 1D texture array  */
1433179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[0][1][0] = 0.0f; /*s*/
1434179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[0][1][1] = r; /*t*/
1435179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[0][1][2] = 0.0f;    /*r*/
1436179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie
1437179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[1][1][0] = 1.0f;
1438179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[1][1][1] = r;
1439179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[1][1][2] = 0.0f;
1440179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie
1441179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[2][1][0] = 1.0f;
1442179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[2][1][1] = r;
1443179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[2][1][2] = 0.0f;
1444179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie
1445179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[3][1][0] = 0.0f;
1446179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[3][1][1] = r;
1447179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      ctx->vertices[3][1][2] = 0.0f;
1448179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie   } else {
1449179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      /* 1D/2D/3D/2D array */
145079ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[0][1][0] = 0.0f; /*s*/
145179ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[0][1][1] = 0.0f; /*t*/
14524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      ctx->vertices[0][1][2] = r;    /*r*/
145379ada8c6331a801a0475f38a540670b14e168f19Brian Paul
145479ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[1][1][0] = 1.0f;
145579ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[1][1][1] = 0.0f;
14564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      ctx->vertices[1][1][2] = r;
145779ada8c6331a801a0475f38a540670b14e168f19Brian Paul
145879ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[2][1][0] = 1.0f;
145979ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[2][1][1] = 1.0f;
14604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      ctx->vertices[2][1][2] = r;
146179ada8c6331a801a0475f38a540670b14e168f19Brian Paul
146279ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[3][1][0] = 0.0f;
146379ada8c6331a801a0475f38a540670b14e168f19Brian Paul      ctx->vertices[3][1][1] = 1.0f;
14644c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      ctx->vertices[3][1][2] = r;
146579ada8c6331a801a0475f38a540670b14e168f19Brian Paul   }
1466309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1467d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   offset = get_next_slot( ctx );
1468d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1469287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_buffer_write_nooverlap(ctx->pipe, ctx->vbuf,
147017974949464b75f25f635443067b4495bb451248José Fonseca                               offset, sizeof(ctx->vertices), ctx->vertices);
1471d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell
1472d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   return offset;
1473309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian}
1474309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1475309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1476309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1477f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian/**
1478f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Destroy a mipmap generation context
1479f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian */
1480f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrianvoid
1481f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrianutil_destroy_gen_mipmap(struct gen_mipmap_state *ctx)
1482f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian{
1483f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   struct pipe_context *pipe = ctx->pipe;
14841a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   unsigned i;
1485f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
148691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   for (i = 0; i < Elements(ctx->fs_color); i++)
148791cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      if (ctx->fs_color[i])
148891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         pipe->delete_fs_state(pipe, ctx->fs_color[i]);
148991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák
149091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   for (i = 0; i < Elements(ctx->fs_depth); i++)
149191cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák      if (ctx->fs_depth[i])
149291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         pipe->delete_fs_state(pipe, ctx->fs_depth[i]);
14931a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz
14941a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   if (ctx->vs)
14951a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      pipe->delete_vs_state(pipe, ctx->vs);
1496f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1497287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   pipe_resource_reference(&ctx->vbuf, NULL);
1498309d6e52c5c1cdeca1434cbe29e869b9176e5fa5Brian
1499f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   FREE(ctx);
1500f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian}
1501f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1502f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1503f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian/**
1504f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * Generate mipmap images.  It's assumed all needed texture memory is
1505f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * already allocated.
1506f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian *
15078f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger * \param psv  the sampler view to the texture to generate mipmap levels for
1508f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * \param face  which cube face to generate mipmaps for (0 for non-cube maps)
1509f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * \param baseLevel  the first mipmap level to use as a src
1510f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian * \param lastLevel  the last mipmap level to generate
15116edaef531806f4ac6c92c4a2934da5a37262e2e3Michal Krol * \param filter  the minification filter used to generate mipmap levels with
1512110b63d00fa0a555a00f5b1560452323517eafe1Brian * \param filter  one of PIPE_TEX_FILTER_LINEAR, PIPE_TEX_FILTER_NEAREST
1513f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian */
1514f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrianvoid
1515110b63d00fa0a555a00f5b1560452323517eafe1Brianutil_gen_mipmap(struct gen_mipmap_state *ctx,
15168f55a95178069d5e8b18647e6b675fc403d68073Roland Scheidegger                struct pipe_sampler_view *psv,
1517110b63d00fa0a555a00f5b1560452323517eafe1Brian                uint face, uint baseLevel, uint lastLevel, uint filter)
1518f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian{
1519f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   struct pipe_context *pipe = ctx->pipe;
1520f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   struct pipe_screen *screen = pipe->screen;
1521f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   struct pipe_framebuffer_state fb;
1522287c94ea4987033f9c99a2f91c5750c9083504caKeith Whitwell   struct pipe_resource *pt = psv->texture;
1523f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   uint dstLevel;
1524d2c2e9316d043ab584794a3524f22776deb4c777Keith Whitwell   uint offset;
15251a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   uint type;
152691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   boolean is_depth = util_format_is_depth_or_stencil(psv->format);
1527f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
152841d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul   /* The texture object should have room for the levels which we're
152941d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul    * about to generate.
153041d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul    */
153141d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul   assert(lastLevel <= pt->last_level);
153241d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul
153341d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul   /* If this fails, why are we here? */
153441d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul   assert(lastLevel > baseLevel);
153541d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul
153641d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul   assert(filter == PIPE_TEX_FILTER_LINEAR ||
153741d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul          filter == PIPE_TEX_FILTER_NEAREST);
153841d0606b7f4666c31db31bec3c54934ef6cd16e7Brian Paul
15394c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   switch (pt->target) {
15404c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_1D:
15411a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_1D;
15424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      break;
15434c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_2D:
15441a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_2D;
15454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      break;
15464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_3D:
15471a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_3D;
15484c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      break;
15494c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_CUBE:
15501a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_CUBE;
15514c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      break;
15524c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_1D_ARRAY:
15531a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_1D_ARRAY;
1554179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      break;
15554c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   case PIPE_TEXTURE_2D_ARRAY:
15561a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_2D_ARRAY;
1557179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      break;
15584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   default:
15594c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      assert(0);
15601a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz      type = TGSI_TEXTURE_2D;
15614c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   }
15624c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
1563f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   /* check if we can render in the texture's format */
15644c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger   if (!screen->is_format_supported(screen, psv->format, pt->target,
156591cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                    pt->nr_samples,
156691cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                    is_depth ? PIPE_BIND_DEPTH_STENCIL :
156791cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                               PIPE_BIND_RENDER_TARGET)) {
1568f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian      fallback_gen_mipmap(ctx, pt, face, baseLevel, lastLevel);
1569f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian      return;
1570f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   }
1571f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
15727d95efde0a0e13e13c59444703bc47eb13926385Brian   /* save state (restored below) */
15737d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_save_blend(ctx->cso);
15747d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_save_depth_stencil_alpha(ctx->cso);
15757d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_save_rasterizer(ctx->cso);
1576e7689303a8e4790c38cc69ae7a197712f98e8f5bMarek Olšák   cso_save_sample_mask(ctx->cso);
1577ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul   cso_save_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
1578ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul   cso_save_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
1579c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák   cso_save_stream_outputs(ctx->cso);
15807d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_save_framebuffer(ctx->cso);
158113d8b1b211a803f44ffe325e7eed887cce4abacaJosé Fonseca   cso_save_fragment_shader(ctx->cso);
158213d8b1b211a803f44ffe325e7eed887cce4abacaJosé Fonseca   cso_save_vertex_shader(ctx->cso);
1583d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák   cso_save_geometry_shader(ctx->cso);
158463cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   cso_save_viewport(ctx->cso);
1585ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   cso_save_vertex_elements(ctx->cso);
158695ce454c8c4397a67aa038d91667882e413314d3Stuart Abercrombie   cso_save_vertex_buffers(ctx->cso);
1587f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
1588f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   /* bind our state */
158991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   cso_set_blend(ctx->cso, is_depth ? &ctx->blend_keep_color :
159091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                      &ctx->blend_write_color);
159191cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   cso_set_depth_stencil_alpha(ctx->cso, is_depth ? &ctx->dsa_write_depth :
159291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                                    &ctx->dsa_keep_depth);
15937d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_set_rasterizer(ctx->cso, &ctx->rasterizer);
1594e7689303a8e4790c38cc69ae7a197712f98e8f5bMarek Olšák   cso_set_sample_mask(ctx->cso, ~0);
1595ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   cso_set_vertex_elements(ctx->cso, 2, ctx->velem);
1596c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák   cso_set_stream_outputs(ctx->cso, 0, NULL, 0);
15977d95efde0a0e13e13c59444703bc47eb13926385Brian
159891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák   set_fragment_shader(ctx, type, is_depth);
15991a79064da12a8be71dca7656e5eebc4b85d2b35fJakob Bornecrantz   set_vertex_shader(ctx);
1600d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák   cso_set_geometry_shader_handle(ctx->cso, NULL);
1601f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
16027d95efde0a0e13e13c59444703bc47eb13926385Brian   /* init framebuffer state */
16037d95efde0a0e13e13c59444703bc47eb13926385Brian   memset(&fb, 0, sizeof(fb));
16047d95efde0a0e13e13c59444703bc47eb13926385Brian
1605d83e75c75958673e8019475f5ba5c2cff9b8415fBrian   /* set min/mag to same filter for faster sw speed */
1606d83e75c75958673e8019475f5ba5c2cff9b8415fBrian   ctx->sampler.mag_img_filter = filter;
1607d83e75c75958673e8019475f5ba5c2cff9b8415fBrian   ctx->sampler.min_img_filter = filter;
1608d83e75c75958673e8019475f5ba5c2cff9b8415fBrian
1609f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   for (dstLevel = baseLevel + 1; dstLevel <= lastLevel; dstLevel++) {
1610f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian      const uint srcLevel = dstLevel - 1;
161163cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol      struct pipe_viewport_state vp;
16124c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      unsigned nr_layers, layer, i;
16134c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      float rcoord = 0.0f;
16144c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16154c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      if (pt->target == PIPE_TEXTURE_3D)
16164c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         nr_layers = u_minify(pt->depth0, dstLevel);
1617179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie      else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY)
1618179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie	 nr_layers = pt->array_size;
16194fc62a074c5cc7e55a81c2a24cc5ef2f1452e948Brian Paul      else
16204fc62a074c5cc7e55a81c2a24cc5ef2f1452e948Brian Paul         nr_layers = 1;
16214c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16224c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      for (i = 0; i < nr_layers; i++) {
16234c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         struct pipe_surface *surf, surf_templ;
16244c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         if (pt->target == PIPE_TEXTURE_3D) {
16254c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            /* in theory with geom shaders and driver with full layer support
16264c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger               could do that in one go. */
16274c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            layer = i;
16284c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            /* XXX hmm really? */
16294c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            rcoord = (float)layer / (float)nr_layers + 1.0f / (float)(nr_layers * 2);
1630179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie         } else if (pt->target == PIPE_TEXTURE_2D_ARRAY || pt->target == PIPE_TEXTURE_1D_ARRAY) {
1631179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie	    layer = i;
1632179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie	    rcoord = (float)layer;
1633179ff0551c4938e59f4b57fec0a10d63f012d7c6Dave Airlie	 } else
16344c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger            layer = face;
16354c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16364c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         memset(&surf_templ, 0, sizeof(surf_templ));
163791cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         u_surface_default_template(&surf_templ, pt,
163891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                    is_depth ? PIPE_BIND_DEPTH_STENCIL :
163991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák                                               PIPE_BIND_RENDER_TARGET);
16404c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         surf_templ.u.tex.level = dstLevel;
16414c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         surf_templ.u.tex.first_layer = layer;
16424c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         surf_templ.u.tex.last_layer = layer;
16434c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         surf = pipe->create_surface(pipe, pt, &surf_templ);
16444c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16454c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /*
16464c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * Setup framebuffer / dest surface
16474c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          */
164891cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         if (is_depth) {
164991cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            fb.nr_cbufs = 0;
165091cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            fb.zsbuf = surf;
165191cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         }
165291cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         else {
165391cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            fb.nr_cbufs = 1;
165491cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák            fb.cbufs[0] = surf;
165591cf9fe98838f35ea939ae9e44af87410f60fae9Marek Olšák         }
16564c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         fb.width = u_minify(pt->width0, dstLevel);
16574c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         fb.height = u_minify(pt->height0, dstLevel);
16584c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         cso_set_framebuffer(ctx->cso, &fb);
16594c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16604c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /* viewport */
16614c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.scale[0] = 0.5f * fb.width;
16624c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.scale[1] = 0.5f * fb.height;
16634c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.scale[2] = 1.0f;
16644c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.scale[3] = 1.0f;
16654c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.translate[0] = 0.5f * fb.width;
16664c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.translate[1] = 0.5f * fb.height;
16674c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.translate[2] = 0.0f;
16684c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         vp.translate[3] = 0.0f;
16694c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         cso_set_viewport(ctx->cso, &vp);
16704c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16714c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /*
16724c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * Setup sampler state
16734c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * Note: we should only have to set the min/max LOD clamps to ensure
16744c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * we grab texels from the right mipmap level.  But some hardware
16754c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * has trouble with min clamping so we also set the lod_bias to
16764c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          * try to work around that.
16774c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger          */
16784c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         ctx->sampler.min_lod = ctx->sampler.max_lod = (float) srcLevel;
16794c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         ctx->sampler.lod_bias = (float) srcLevel;
1680ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul         cso_single_sampler(ctx->cso, PIPE_SHADER_FRAGMENT, 0, &ctx->sampler);
1681ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul         cso_single_sampler_done(ctx->cso, PIPE_SHADER_FRAGMENT);
16824c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
1683ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul         cso_set_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT, 1, &psv);
16844c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16854c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /* quad coords in clip coords */
16864c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         offset = set_vertex_data(ctx,
16874c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                  pt->target,
16884c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                  face,
16894c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                  rcoord);
16904c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
1691d5062fb3a315c46d77d5c954a3e3c14be1907d33Marek Olšák         util_draw_vertex_buffer(ctx->pipe,
1692d5062fb3a315c46d77d5c954a3e3c14be1907d33Marek Olšák                                 ctx->cso,
16934c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 ctx->vbuf,
16944c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 offset,
16954c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 PIPE_PRIM_TRIANGLE_FAN,
16964c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 4,  /* verts */
16974c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger                                 2); /* attribs/vert */
16984c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger
16994c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         /* need to signal that the texture has changed _after_ rendering to it */
17004c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger         pipe_surface_reference( &surf, NULL );
17014c7001462607e6e99e474d6271dd481d3f8f201cRoland Scheidegger      }
1702f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian   }
1703f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian
17047d95efde0a0e13e13c59444703bc47eb13926385Brian   /* restore state we changed */
17057d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_restore_blend(ctx->cso);
17067d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_restore_depth_stencil_alpha(ctx->cso);
17077d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_restore_rasterizer(ctx->cso);
1708e7689303a8e4790c38cc69ae7a197712f98e8f5bMarek Olšák   cso_restore_sample_mask(ctx->cso);
1709ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul   cso_restore_samplers(ctx->cso, PIPE_SHADER_FRAGMENT);
1710ea6f035ae90895bd4ee3247408eb179dfdf96d22Brian Paul   cso_restore_sampler_views(ctx->cso, PIPE_SHADER_FRAGMENT);
17117d95efde0a0e13e13c59444703bc47eb13926385Brian   cso_restore_framebuffer(ctx->cso);
171213d8b1b211a803f44ffe325e7eed887cce4abacaJosé Fonseca   cso_restore_fragment_shader(ctx->cso);
171313d8b1b211a803f44ffe325e7eed887cce4abacaJosé Fonseca   cso_restore_vertex_shader(ctx->cso);
1714d2633af696f2e4ff98f669061e4e222e8643312cMarek Olšák   cso_restore_geometry_shader(ctx->cso);
171563cb6f59eac91ba34cf80ff3736568e40b094fe1Michal Krol   cso_restore_viewport(ctx->cso);
1716ac4abaecd5f52e416c89bfe19b34ed7f4e014b21Roland Scheidegger   cso_restore_vertex_elements(ctx->cso);
1717c05fafa4a0fd93d4264c46578e23a83ecf2b481eMarek Olšák   cso_restore_stream_outputs(ctx->cso);
171895ce454c8c4397a67aa038d91667882e413314d3Stuart Abercrombie   cso_restore_vertex_buffers(ctx->cso);
1719f1b42595d02828bcc617bc88b4ce6cf38a69ddbfBrian}
1720