texstore.c revision 184b5d89380e18008d64adfe1756dca9736426f2
18e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
28e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Mesa 3-D graphics library
3a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul * Version:  6.5.1
48e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
5ef8653a83800bc4b8e116e03ad52604097224378Brian Paul * Copyright (C) 1999-2006  Brian Paul   All Rights Reserved.
68e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
78e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Permission is hereby granted, free of charge, to any person obtaining a
88e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * copy of this software and associated documentation files (the "Software"),
98e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * to deal in the Software without restriction, including without limitation
108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * the rights to use, copy, modify, merge, publish, distribute, sublicense,
118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * and/or sell copies of the Software, and to permit persons to whom the
128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Software is furnished to do so, subject to the following conditions:
138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * The above copyright notice and this permission notice shall be included
158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * in all copies or substantial portions of the Software.
168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *
178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Authors:
278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul *   Brian Paul
288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/*
3189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * The GL texture image functions in teximage.c basically just do
3289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * error checking and data structure allocation.  They in turn call
3389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * device driver functions which actually copy/convert/store the user's
3489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * texture image data.
3589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
3689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * However, most device drivers will be able to use the fallback functions
3789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * in this file.  That is, most drivers will have the following bit of
3889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * code:
3989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage1D = _mesa_store_teximage1d;
4089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage2D = _mesa_store_teximage2d;
4189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   ctx->Driver.TexImage3D = _mesa_store_teximage3d;
4289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *   etc...
4389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Texture image processing is actually kind of complicated.  We have to do:
4589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    Format/type conversions
4689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel unpacking
4789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *    pixel transfer (scale, bais, lookup, convolution!, etc)
4889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul *
4989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * These functions can handle most everything, including processing full
5089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * images and sub-images.
5189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
5289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
5389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
543c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "glheader.h"
557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul#include "bufferobj.h"
56e75d2424e53d6023f4414e40694cd467e5392b96Brian Paul#include "colormac.h"
578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "context.h"
588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "convolve.h"
598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "image.h"
608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "macros.h"
613c63452e64df7e10aa073c6c3b9492b1d7dabbb8Brian Paul#include "imports.h"
6289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul#include "texcompress.h"
63371ef9c058b0d59bfb62689b64af1b29a2214d9eGareth Hughes#include "texformat.h"
648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "teximage.h"
658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul#include "texstore.h"
662e5c686c2b6f356895f33b2815e41386946ab55aKeith Whitwell#include "enums.h"
678e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
68fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwellenum {
69fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   ZERO = 4,
70fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   ONE = 5
71fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell};
7271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
7371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellstatic GLboolean can_swizzle(GLenum logicalBaseFormat)
7471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
7571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   switch (logicalBaseFormat) {
7671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_RGBA:
7771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_RGB:
7871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_LUMINANCE_ALPHA:
7971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_INTENSITY:
8071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_ALPHA:
8171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case GL_LUMINANCE:
823aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_RED:
833aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_GREEN:
843aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BLUE:
853aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BGR:
863aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BGRA:
873aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_ABGR_EXT:
8871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      return GL_TRUE;
8971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   default:
9071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      return GL_FALSE;
9171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
9271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
9371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
943aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
96fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwellenum {
97fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_LUMINANCE = 0,
98fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_ALPHA,
99fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_INTENSITY,
100fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_LUMINANCE_ALPHA,
101fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_RGB,
102fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   IDX_RGBA,
1033aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_RED,
1043aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_GREEN,
1053aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_BLUE,
1063aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_BGR,
1073aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_BGRA,
1083aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   IDX_ABGR,
109fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   MAX_IDX
110fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell};
111fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
1123aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell#define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
1133aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell#define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
1143aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell#define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
1153aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell#define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
116fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
117fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
1182e5c686c2b6f356895f33b2815e41386946ab55aKeith Whitwellstatic const struct {
1193aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   GLubyte format_idx;
1203aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   GLubyte to_rgba[6];
1213aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   GLubyte from_rgba[6];
1223aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell} mappings[MAX_IDX] =
123fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell{
124fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1253aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_LUMINANCE,
1263aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0,0,0,ONE),
1273aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(0)
128fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   },
129fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
130fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1313aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_ALPHA,
1323aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(ZERO, ZERO, ZERO, 0),
1333aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(3)
134fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   },
135fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
136fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1373aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_INTENSITY,
1383aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0, 0, 0, 0),
1393aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(0),
140fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   },
141fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
142fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1433aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_LUMINANCE_ALPHA,
1443aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0,0,0,1),
1453aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP2(0,3)
146fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   },
147fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
148fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1493aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_RGB,
1503aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0,1,2,ONE),
1513aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP3(0,1,2)
152fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   },
153fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
154fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   {
1553aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_RGBA,
1563aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0,1,2,3),
1573aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0,1,2,3),
1583aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1593aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1603aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1613aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1623aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_RED,
1633aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(0, ZERO, ZERO, ONE),
1643aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(0),
1653aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1663aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1673aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1683aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_GREEN,
1693aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(ZERO, 0, ZERO, ONE),
1703aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(1),
1713aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1723aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1733aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1743aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_BLUE,
1753aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(ZERO, ZERO, 0, ONE),
1763aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP1(2),
1773aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1783aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1793aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1803aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_BGR,
1813aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(2,1,0,ONE),
1823aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP3(2,1,0)
1833aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1843aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1853aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1863aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_BGRA,
1873aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(2,1,0,3),
1883aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(2,1,0,3)
1893aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
1903aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
1913aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   {
1923aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      IDX_ABGR,
1933aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(3,2,1,0),
1943aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      MAP4(3,2,1,0)
1953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   },
196fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell};
197fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
198fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
199fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
200fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
201fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
202fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
203fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwellstatic int get_map_idx( GLenum value )
204fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell{
205fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   switch (value) {
206fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_LUMINANCE: return IDX_LUMINANCE;
207fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_ALPHA: return IDX_ALPHA;
208fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_INTENSITY: return IDX_INTENSITY;
209fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
210fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_RGB: return IDX_RGB;
211fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   case GL_RGBA: return IDX_RGBA;
2123aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_RED: return IDX_RED;
2133aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_GREEN: return IDX_GREEN;
2143aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BLUE: return IDX_BLUE;
2153aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BGR: return IDX_BGR;
2163aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_BGRA: return IDX_BGRA;
2173aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case GL_ABGR_EXT: return IDX_ABGR;
218fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   default:
219fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell      _mesa_problem(NULL, "Unexpected inFormat");
220fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell      return 0;
221fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   }
222fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell}
223fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell
224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
225f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
226f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * When promoting texture formats (see below) we need to compute the
227f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * mapping of dest components back to source components.
228f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * This function does that.
229fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell * \param inFormat  the incoming format of the texture
230fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell * \param outFormat  the final texture format
231fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell * \return map[6]  a full 6-component map
232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2333aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwellstatic void
2343aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwellcompute_component_mapping(GLenum inFormat, GLenum outFormat,
2353aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell			  GLubyte *map)
236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
237fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   int in = get_map_idx(inFormat);
238fce0d13b4fff04de50fd91a8f4dfdc248b6262e0Keith Whitwell   int out = get_map_idx(outFormat);
2393aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   const GLubyte *in2rgba = mappings[in].to_rgba;
2403aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   const GLubyte *rgba2out = mappings[out].from_rgba;
2413aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   int i;
2422e5c686c2b6f356895f33b2815e41386946ab55aKeith Whitwell
2433aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   for (i = 0; i < 4; i++)
2443aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      map[i] = in2rgba[rgba2out[i]];
2453aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
2463aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   map[ZERO] = ZERO;
2473aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   map[ONE] = ONE;
2483aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
2493aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell/*
2503aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
2513aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		inFormat, _mesa_lookup_enum_by_nr(inFormat),
2523aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		outFormat, _mesa_lookup_enum_by_nr(outFormat),
2533aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[0],
2543aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[1],
2553aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[2],
2563aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[3],
2573aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[4],
2583aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell		map[5]);
2593aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell*/
260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLfloat components.
265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
273f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
274f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
275f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLfloat.
285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic GLfloat *
287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulmake_temp_float_image(GLcontext *ctx, GLuint dims,
288f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum logicalBaseFormat,
289f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum textureBaseFormat,
290f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
291f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      GLenum srcFormat, GLenum srcType,
292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const GLvoid *srcAddr,
293f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                      const struct gl_pixelstore_attrib *srcPacking)
294f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLfloat *tempImage;
297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
303f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
304f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
305f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY ||
306f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_COLOR_INDEX ||
307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_DEPTH_COMPONENT);
308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
310f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
311f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
312f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
313f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
314f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY ||
315f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_COLOR_INDEX ||
316f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_DEPTH_COMPONENT);
317f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
318f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* conventional color image */
319f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
320f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
321f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
322f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
323f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* need image convolution */
324f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint preConvTransferOps
325f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
326f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLuint postConvTransferOps
327f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
328f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
329f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint convWidth, convHeight;
330f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage;
331f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
332f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* pre-convolution image buffer (3D) */
333f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
334f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
335f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
336f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
337f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
338f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* post-convolution image buffer (2D) */
339f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
340f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * 4 * sizeof(GLfloat));
341f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage) {
342f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
343f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
346f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* loop over 3D image slices */
347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* unpack and do transfer ops up to convolution */
351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
35260909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcAddr, srcWidth, srcHeight,
354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                              srcFormat, srcType, img, row, 0);
355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcFormat, srcType, src,
357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking,
358f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          preConvTransferOps);
359f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * 4;
360f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
361f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do convolution */
363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
364f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
365f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convWidth = srcWidth;
366f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            convHeight = srcHeight;
367f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (dims == 1) {
368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ASSERT(ctx->Pixel.Convolution1DEnabled);
369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               if (ctx->Pixel.Convolution2DEnabled) {
373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          src, convImage);
375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               else {
377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  ASSERT(ctx->Pixel.Separable2DEnabled);
378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
379f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           src, convImage);
380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
381f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         /* do post-convolution transfer and pack into tempImage */
385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         {
3862b012578ee519561365640e23272b71898378c45Brian Paul            const GLint logComponents
3872b012578ee519561365640e23272b71898378c45Brian Paul               = _mesa_components_in_format(logicalBaseFormat);
388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            const GLfloat *src = convImage;
389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (row = 0; row < convHeight; row++) {
391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               _mesa_pack_rgba_span_float(ctx, convWidth,
392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          (const GLfloat (*)[4]) src,
393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          logicalBaseFormat, GL_FLOAT,
394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, &ctx->DefaultPacking,
395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          postConvTransferOps);
396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += convWidth * 4;
3972b012578ee519561365640e23272b71898378c45Brian Paul               dst += convWidth * logComponents;
398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      } /* loop over 3D image slices */
401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
402f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(convImage);
403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* might need these below */
405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcWidth = convWidth;
406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcHeight = convHeight;
407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* no convolution */
410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint components = _mesa_components_in_format(logicalBaseFormat);
411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *dst;
414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
417f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                           * components * sizeof(GLfloat));
418f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      dst = tempImage;
422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
423f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *src
42460909388ab136d849d99eab49e782a53772a618fBrian Paul            = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
425f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcWidth, srcHeight,
426f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    srcFormat, srcType,
427f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    img, 0, 0);
428f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
430f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          dst, srcFormat, srcType, src,
431f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          srcPacking, transferOps);
432f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst += srcWidth * components;
433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcStride;
434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* more work */
440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *newImage;
443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
4443aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte map[6];
445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
44613ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
44713ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
44813ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                          * texComponents * sizeof(GLfloat));
457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
4623aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
469f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
470f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0.0F;
471f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
472f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 1.0F;
473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Make a temporary (color) texture image with GLchan components.
488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Apply all needed pixel unpacking and pixel transfer operations.
489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
490f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Suppose the user specifies GL_LUMINANCE as the internal texture format
491f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * but the graphics hardware doesn't support luminance textures.  So, might
492f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * use an RGB hardware format instead.
493f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param ctx  the rendering context
496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param dims  image dimensions: 1, 2 or 3
497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param logicalBaseFormat  basic texture derived from the user's
498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *    internal texture format value
499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param textureBaseFormat  the actual basic format of the texture
500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcWidth  source image width
501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcHeight  source image height
502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcDepth  source image depth
503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcFormat  source image format
504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcType  source image type
505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcAddr  source image address
506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \param srcPacking  source image pixel packing
507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * \return resulting image with format = textureBaseFormat and type = GLchan.
508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
5098f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian PaulGLchan *
5108f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul_mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
5118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum logicalBaseFormat,
5128f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum textureBaseFormat,
5138f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
5148f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           GLenum srcFormat, GLenum srcType,
5158f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const GLvoid *srcAddr,
5168f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                           const struct gl_pixelstore_attrib *srcPacking)
517f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
518f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLuint transferOps = ctx->_ImageTransferState;
519f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(logicalBaseFormat);
520f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLboolean freeSrcImage = GL_FALSE;
521f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint img, row;
522f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLchan *tempImage, *dst;
523f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
524f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dims >= 1 && dims <= 3);
525f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
526f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(logicalBaseFormat == GL_RGBA ||
527f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_RGB ||
528f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE_ALPHA ||
529f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_LUMINANCE ||
530f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_ALPHA ||
531f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          logicalBaseFormat == GL_INTENSITY);
532f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
533f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(textureBaseFormat == GL_RGBA ||
534f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_RGB ||
535f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE_ALPHA ||
536f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_LUMINANCE ||
537f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_ALPHA ||
538f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          textureBaseFormat == GL_INTENSITY);
539f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
540f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
541f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* get convolved image */
544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLfloat *convImage = make_temp_float_image(ctx, dims,
545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 logicalBaseFormat,
547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcAddr, srcPacking);
550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!convImage)
551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* the convolved image is our new source image */
553f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcAddr = convImage;
554f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcFormat = logicalBaseFormat;
555f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcType = GL_FLOAT;
556f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      srcPacking = &ctx->DefaultPacking;
557f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
558f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      transferOps = 0;
559f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      freeSrcImage = GL_TRUE;
560f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
561f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
562f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* unpack and transfer the source image */
563f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
564f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                       * components * sizeof(GLchan));
565f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!tempImage)
566f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return NULL;
567f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
568f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   dst = tempImage;
569f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   for (img = 0; img < srcDepth; img++) {
570f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLint srcStride = _mesa_image_row_stride(srcPacking,
571f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcWidth, srcFormat,
572f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcType);
573f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLubyte *src
57460909388ab136d849d99eab49e782a53772a618fBrian Paul         = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
575f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight,
576f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType,
577f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 img, 0, 0);
578f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (row = 0; row < srcHeight; row++) {
5799c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul         _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
5809c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      srcFormat, srcType, src, srcPacking,
5819c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul                                      transferOps);
582f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dst += srcWidth * components;
583f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         src += srcStride;
584f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
585f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
586f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
587f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* If we made a temporary image for convolution, free it here */
588f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (freeSrcImage) {
589f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) srcAddr);
590f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
591f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
592f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (logicalBaseFormat != textureBaseFormat) {
593f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one more conversion step */
594f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint texComponents = _mesa_components_in_format(textureBaseFormat);
595f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
596f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLchan *newImage;
597f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint i, n;
5983aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte map[6];
599f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
60013ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
60113ad04719e292a2bee7e1b3155da74a97921c035Brian Paul      ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
60213ad04719e292a2bee7e1b3155da74a97921c035Brian Paul             textureBaseFormat == GL_LUMINANCE_ALPHA);
603f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
604f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* The actual texture format should have at least as many components
605f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       * as the logical texture format.
606f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       */
607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texComponents >= logComponents);
608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
609f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
6102dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul                                         * texComponents * sizeof(GLchan));
611f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!newImage) {
612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_free(tempImage);
613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return NULL;
614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
6163aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      n = srcWidth * srcHeight * srcDepth;
619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (i = 0; i < n; i++) {
620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLint k;
621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (k = 0; k < texComponents; k++) {
622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint j = map[k];
623f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (j == ZERO)
624f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = 0;
625f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else if (j == ONE)
626f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = CHAN_MAX;
627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else
628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               newImage[i * texComponents + k] = tempImage[i * logComponents + j];
629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free(tempImage);
633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      tempImage = newImage;
634f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
635f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return tempImage;
637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
639f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
640c039af165d5919008c6df599795951f85dea164dBrian Paul/**
641c039af165d5919008c6df599795951f85dea164dBrian Paul * Copy GLubyte pixels from <src> to <dst> with swizzling.
642c039af165d5919008c6df599795951f85dea164dBrian Paul * \param dst  destination pixels
643c039af165d5919008c6df599795951f85dea164dBrian Paul * \param dstComponents  number of color components in destination pixels
644c039af165d5919008c6df599795951f85dea164dBrian Paul * \param src  source pixels
645c039af165d5919008c6df599795951f85dea164dBrian Paul * \param srcComponents  number of color components in source pixels
646c039af165d5919008c6df599795951f85dea164dBrian Paul * \param map  the swizzle mapping
647c039af165d5919008c6df599795951f85dea164dBrian Paul * \param count  number of pixels to copy/swizzle.
648c039af165d5919008c6df599795951f85dea164dBrian Paul */
649c039af165d5919008c6df599795951f85dea164dBrian Paulstatic void
650c039af165d5919008c6df599795951f85dea164dBrian Paulswizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
651c039af165d5919008c6df599795951f85dea164dBrian Paul             GLuint srcComponents, const GLubyte *map, GLuint count)
65271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
65371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLubyte tmp[8];
654edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul   GLuint i;
65571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
65671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   tmp[ZERO] = 0x0;
65771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   tmp[ONE] = 0xff;
65871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
65971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   switch (dstComponents) {
66071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 4:
66171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
66271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
66371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
66471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
66571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
66671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[2] = tmp[map[2]];
66771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[3] = tmp[map[3]];
66871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 4;
66971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
67071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
67171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 3:
67271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
67371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
67471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
67571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
67671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
67771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[2] = tmp[map[2]];
67871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 3;
67971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
68071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
68171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   case 2:
68271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (i = 0; i < count; i++) {
68371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell 	 COPY_4UBV(tmp, src);
68471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 src += srcComponents;
68571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[0] = tmp[map[0]];
68671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst[1] = tmp[map[1]];
68771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	 dst += 2;
68871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
68971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      break;
6903aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   case 1:
6913aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      for (i = 0; i < count; i++) {
6923aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell 	 COPY_4UBV(tmp, src);
6933aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 src += srcComponents;
6943aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dst[0] = tmp[map[0]];
6953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dst += 1;
6963aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      }
6973aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      break;
69871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
69971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
70071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
70146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell/* Help! I'm just making this up!
70246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell *
70346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * This should take the incoming Type, Endian pair and produce a
70446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * mapping from that data when examined through a (char *) pointer
70546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * natively, to the equivalent of what that data would look like if it
70646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * were presented as GL_UNSIGNED_BYTEs on a littleEndian machine... I
70746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * think...
70846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell */
70946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwellstatic const GLubyte map_identity[6] = { 0, 1, 2, 3, 4, 5 };
71046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwellstatic const GLubyte map_3210[6] = { 3, 2, 1, 0, 4, 5 };
71146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
71246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
71346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwellstatic const GLubyte *
7143aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwelltype_endian_mapping( GLenum srcType )
71546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell{
71646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   switch (srcType) {
71746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_BYTE:
718184b5d89380e18008d64adfe1756dca9736426f2Brian Paul      if (_mesa_little_endian())
71946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 return map_identity;
72046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      else
72146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 return map_3210;
72246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_INT_8_8_8_8:
72346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return map_identity;
72446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_INT_8_8_8_8_REV:
72546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return map_3210;
72646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   default:
72746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return NULL;
72846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   }
72946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell}
73046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
73146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell/* This will have to change to support GL_UNSIGNED_SHORT input types.
73246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell * It's making my mind swim at the moment though.
73346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell */
73446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwellstatic const GLubyte *
73546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwellbyteswap_mapping( GLenum srcType )
73646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell{
73746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   switch (srcType) {
73846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_BYTE:
73946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return map_identity;
74046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_INT_8_8_8_8:
74146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   case GL_UNSIGNED_INT_8_8_8_8_REV:
74246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return map_3210;
74346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   default:
74446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      return NULL;
74546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   }
74646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell}
74746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
74846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
74946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
75071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
751c039af165d5919008c6df599795951f85dea164dBrian Paul/**
752c039af165d5919008c6df599795951f85dea164dBrian Paul * Transfer a GLubyte texture image with component swizzling.
753c039af165d5919008c6df599795951f85dea164dBrian Paul */
75471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellstatic void
75571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_swizzle_ubyte_image(GLcontext *ctx,
75671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLuint dimensions,
75771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLenum srcFormat,
75846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell			  GLenum srcType,
75946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
7600c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell			  GLenum baseInternalFormat,
7610c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell
76246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell			  const GLubyte *rgba2dst,
7630c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell			  GLuint dstComponents,
76471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
76571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLvoid *dstAddr,
76671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
767b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul			  GLint dstRowStride,
768b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                          const GLuint *dstImageOffsets,
76971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
77071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  GLint srcWidth, GLint srcHeight, GLint srcDepth,
77171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const GLvoid *srcAddr,
77271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			  const struct gl_pixelstore_attrib *srcPacking )
77371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell{
77471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint srcComponents = _mesa_components_in_format(srcFormat);
7753aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   const GLubyte *srctype2ubyte_le, *swap;
7763aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   GLubyte map[4], src2base[6], base2rgba[6];
77771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   GLint i;
778c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcRowStride =
779c039af165d5919008c6df599795951f85dea164dBrian Paul      _mesa_image_row_stride(srcPacking, srcWidth,
780c039af165d5919008c6df599795951f85dea164dBrian Paul                             srcFormat, GL_UNSIGNED_BYTE);
781c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLint srcImageStride
782c039af165d5919008c6df599795951f85dea164dBrian Paul      = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
783c039af165d5919008c6df599795951f85dea164dBrian Paul                                 GL_UNSIGNED_BYTE);
784c039af165d5919008c6df599795951f85dea164dBrian Paul   const GLubyte *srcImage
785c039af165d5919008c6df599795951f85dea164dBrian Paul      = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
786c039af165d5919008c6df599795951f85dea164dBrian Paul                                              srcWidth, srcHeight, srcFormat,
787c039af165d5919008c6df599795951f85dea164dBrian Paul                                              GL_UNSIGNED_BYTE, 0, 0, 0);
78871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
789edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul   (void) ctx;
790edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul
7910c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell   /* Translate from src->baseInternal->GL_RGBA->dst.  This will
7920c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell    * correctly deal with RGBA->RGB->RGBA conversions where the final
7930c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell    * A value must be 0xff regardless of the incoming alpha values.
7940c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell    */
7953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   compute_component_mapping(srcFormat, baseInternalFormat, src2base);
7963aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
79746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell   swap = byteswap_mapping(srcType);
7983aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   srctype2ubyte_le = type_endian_mapping(srcType);
79946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
80071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
80171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   for (i = 0; i < 4; i++)
80246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      map[i] = srctype2ubyte_le[swap[src2base[base2rgba[rgba2dst[i]]]]];
80371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
8042e5c686c2b6f356895f33b2815e41386946ab55aKeith Whitwell/*    _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
8052e5c686c2b6f356895f33b2815e41386946ab55aKeith Whitwell
80671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   if (srcRowStride == srcWidth * srcComponents &&
807b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul       dimensions < 3) {
808b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      /* 1 and 2D images only */
809b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLubyte *dstImage = (GLubyte *) dstAddr
810b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstYoffset * dstRowStride
811b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstXoffset * dstComponents;
81271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
813b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul		   srcWidth * srcHeight);
81471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
81571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else {
81671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLint img, row;
81771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
81871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLubyte *srcRow = srcImage;
819b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
820b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstComponents
821b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
822b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstComponents;
82371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
82471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
82571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
82671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
82771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
82871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         srcImage += srcImageStride;
82971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
83071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
83171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell}
83271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
83371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Teximage storage routine for when a simple memcpy will do.
836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * No pixel transfer operations or special texel encodings allowed.
837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * 1D, 2D and 3D images supported.
838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paulstatic void
84017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwellmemcpy_texture(GLcontext *ctx,
84117bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell	       GLuint dimensions,
84260909388ab136d849d99eab49e782a53772a618fBrian Paul               const struct gl_texture_format *dstFormat,
843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLvoid *dstAddr,
844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
845b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               GLint dstRowStride,
846b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               const GLuint *dstImageOffsets,
847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLenum srcFormat, GLenum srcType,
849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const GLvoid *srcAddr,
850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               const struct gl_pixelstore_attrib *srcPacking)
851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                     srcFormat, srcType);
854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                      srcWidth, srcHeight, srcFormat, srcType);
85660909388ab136d849d99eab49e782a53772a618fBrian Paul   const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
85760909388ab136d849d99eab49e782a53772a618fBrian Paul        srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerRow = srcWidth * dstFormat->TexelBytes;
859b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
860b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#if 0
861b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* XXX update/re-enable for dstImageOffsets array */
862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerImage = srcHeight * bytesPerRow;
863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint bytesPerTexture = srcDepth * bytesPerImage;
864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLubyte *dstImage = (GLubyte *) dstAddr
865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstZoffset * dstImageStride
866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstYoffset * dstRowStride
867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     + dstXoffset * dstFormat->TexelBytes;
868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (dstRowStride == srcRowStride &&
870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       dstRowStride == bytesPerRow &&
871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((dstImageStride == srcImageStride &&
872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImageStride == bytesPerImage) ||
873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul        (srcDepth == 1))) {
874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* one big memcpy */
87517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
877b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   else
878b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   {
879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLubyte *srcRow = srcImage;
882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLubyte *dstRow = dstImage;
883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
88417bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell            ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         srcImage += srcImageStride;
889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         dstImage += dstImageStride;
890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
892b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#endif
893b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
894b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   GLint img, row;
895b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   for (img = 0; img < srcDepth; img++) {
896b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLubyte *srcRow = srcImage;
897b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLubyte *dstRow = (GLubyte *) dstAddr
898b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
899b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstYoffset * dstRowStride
900b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         + dstXoffset * dstFormat->TexelBytes;
901b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      for (row = 0; row < srcHeight; row++) {
902b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
903b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRow += dstRowStride;
904b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         srcRow += srcRowStride;
905b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      }
906b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      srcImage += srcImageStride;
907b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   }
908f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
909f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
911f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
912f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba
915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb
916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha
917f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance
918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha
919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity
920f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *
921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
922f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
923b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba(TEXSTORE_PARAMS)
924f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
925f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   const GLint components = _mesa_components_in_format(baseInternalFormat);
926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba ||
928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb ||
929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha ||
930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance ||
931f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha ||
932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity);
933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLchan));
940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
943f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
944f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == CHAN_TYPE) {
945f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
94617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
94760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
948b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
949b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
950f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
951f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
952f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
953f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
954f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
955f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstFormat == &_mesa_texformat_rgb &&
956f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == CHAN_TYPE) {
958f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* extract RGB from RGBA */
959b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
960f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
961b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLchan *dstImage = (GLchan *)
962b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            ((GLubyte *) dstAddr
963b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
964b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstYoffset * dstRowStride
965b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul             + dstXoffset * dstFormat->TexelBytes);
966b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
967f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
968f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
96960909388ab136d849d99eab49e782a53772a618fBrian Paul         GLchan *srcRow = (GLchan *) _mesa_image_address(dims, srcPacking,
97060909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
971f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLchan *dstRow = dstImage;
972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
974f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + RCOMP] = srcRow[col * 4 + RCOMP];
975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + GCOMP] = srcRow[col * 4 + GCOMP];
976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + BCOMP] = srcRow[col * 4 + BCOMP];
977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
978edc16a5f7a89584490be0824a1d96e2f3426998bBrian Paul            dstRow += dstRowStride / sizeof(GLchan);
979f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow = (GLchan *) ((GLubyte *) srcRow + srcRowStride);
980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
9833aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   else if (!ctx->_ImageTransferState &&
9843aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    CHAN_TYPE == GL_UNSIGNED_BYTE &&
9853aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    (srcType == GL_UNSIGNED_BYTE ||
9863aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
9873aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
9883aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(baseInternalFormat) &&
9893aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(srcFormat)) {
9903aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
9913974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      const GLubyte *dstmap;
9923974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      GLuint components;
9933aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
9943aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
9953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell       */
9963974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      if (dstFormat == &_mesa_texformat_rgba) {
9973974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_RGBA].from_rgba;
9983974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 4;
9993974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10003974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else if (dstFormat == &_mesa_texformat_rgb) {
10013974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_RGB].from_rgba;
10023974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 3;
10033974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10043974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else if (dstFormat == &_mesa_texformat_alpha) {
10053974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_ALPHA].from_rgba;
10063974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 1;
10073974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10083974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else if (dstFormat == &_mesa_texformat_luminance) {
10093974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_LUMINANCE].from_rgba;
10103974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 1;
10113974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10123974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else if (dstFormat == &_mesa_texformat_luminance_alpha) {
10133974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_LUMINANCE_ALPHA].from_rgba;
10143974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 2;
10153974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10163974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else if (dstFormat == &_mesa_texformat_intensity) {
10173974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = mappings[IDX_INTENSITY].from_rgba;
10183974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 1;
10193974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10203974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      else {
10213974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 ASSERT(0);
10223974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 dstmap = map_identity;
10233974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell	 components = 4;
10243974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell      }
10253974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell
10263aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
10273aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcFormat,
10283aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcType,
10293aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				baseInternalFormat,
10303974cc8c09a00274f87c418cb295ed0cdd7c9d1eKeith Whitwell				dstmap, components,
10313aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
10323aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstRowStride, dstImageOffsets,
10333aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
10343aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcPacking);
10353aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   }
1036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
10388f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1044f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
10459c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
1046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1047f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
10509c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLchan);
1051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1052b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1053b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1054b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1055b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_memcpy(dstRow, src, bytesPerRow);
1058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
1060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1062f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1063f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1064f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1065f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1066f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1067f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1068f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1069f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1070a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul * Store a 32-bit integer depth component texture image.
1071f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1072f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1073b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z32(TEXSTORE_PARAMS)
1074f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1075a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = (GLfloat) 0xffffffff;
1076a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
1077a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z32);
1078a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLuint));
1079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1082a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
1083a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_DEPTH_COMPONENT &&
1084a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul       srcType == GL_UNSIGNED_INT) {
1085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
108617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
108760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1088b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1089b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1095f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
1096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1097b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1098b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1099b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1100b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
110260909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
11041ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
1105a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_INT, (GLuint *) dstRow,
1106a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    depthScale, srcType, src, srcPacking);
1107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1110f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1114b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul#define STRIDE_3D 0
1115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1117a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul * Store a 16-bit integer depth component texture image.
1118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1120b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z16(TEXSTORE_PARAMS)
1121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1122a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   const GLfloat depthScale = 65535.0f;
1123a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims;
1124a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z16);
1125a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == sizeof(GLushort));
1126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_DEPTH_COMPONENT &&
1130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_DEPTH_COMPONENT &&
1131a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT) {
1132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
113317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
113460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1135b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1136b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
11421ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul      GLint img, row;
1143f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1144b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1145b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1146b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1147b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
114960909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
1150f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1151a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dst16 = (GLushort *) dstRow;
11521ad7b99925e044f82e635f746c1ef2df77f69ac9Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
1153a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul                                    GL_UNSIGNED_SHORT, dst16, depthScale,
1154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking);
1155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1157f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1158f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
1164defb035b6cf03c555318d9dd48864242ed036f39Brian Paul * Store an rgb565 or rgb565_rev texture image.
1165f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
1166f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1167b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb565(TEXSTORE_PARAMS)
1168f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1169defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb565 ||
1170defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgb565_rev);
1171a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 2);
1172f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1173f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1174f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1175defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgb565 &&
1176a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1177a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1178a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_SHORT_5_6_5) {
1179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
118017bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
118160909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1182b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1183b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1187a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1188a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1189a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            baseInternalFormat == GL_RGB &&
1190a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGB &&
1191a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE &&
1192a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dims == 2) {
1193a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* do optimized tex store */
1194a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
1195a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                        srcFormat, srcType);
1196a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLubyte *src = (const GLubyte *)
119760909388ab136d849d99eab49e782a53772a618fBrian Paul         _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1198a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                             srcFormat, srcType, 0, 0, 0);
1199a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLubyte *dst = (GLubyte *) dstAddr
1200a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstYoffset * dstRowStride
1201a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                   + dstXoffset * dstFormat->TexelBytes;
1202a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint row, col;
1203a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (row = 0; row < srcHeight; row++) {
1204a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLubyte *srcUB = (const GLubyte *) src;
1205a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         GLushort *dstUS = (GLushort *) dst;
1206defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         /* check for byteswapped format */
1207f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         if (dstFormat == &_mesa_texformat_rgb565) {
1208f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
1209f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1210f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
1211f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1212f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         }
1213f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul         else {
1214f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            for (col = 0; col < srcWidth; col++) {
1215f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1216f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               srcUB += 3;
1217f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1218defb035b6cf03c555318d9dd48864242ed036f39Brian Paul         }
1219a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         dst += dstRowStride;
1220a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         src += srcRowStride;
1221a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1222a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
1225a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1226a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1227a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1228a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1229a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1230a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1231a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1233a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1234a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1235a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1236f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1237b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1238b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1239b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1240b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1241f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1242a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLushort *dstUS = (GLushort *) dstRow;
1243defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            /* check for byteswapped format */
1244f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgb565) {
1245f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1246f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1247f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[GCOMP]),
1248f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                               CHAN_TO_UBYTE(src[BCOMP]) );
1249f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1250f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1251f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            }
1252f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1253f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1254f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1255f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[GCOMP]),
1256f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                   CHAN_TO_UBYTE(src[BCOMP]) );
1257f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 3;
1258f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1260f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1261f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1270b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1272184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
127371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
1274defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba8888 ||
1275defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_rgba8888_rev);
1276f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1280defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_rgba8888 &&
1281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1282defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
12832e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
12842e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
12852e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
12862e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       /* simple memcpy path */
12872e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger      memcpy_texture(ctx, dims,
12882e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
12892e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger                     dstRowStride,
12902e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger                     dstImageOffsets,
12912e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
12922e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger                     srcAddr, srcPacking);
12932e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger   }
12942e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger   else if (!ctx->_ImageTransferState &&
12952e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       !srcPacking->SwapBytes &&
12962e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       dstFormat == &_mesa_texformat_rgba8888_rev &&
12972e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       baseInternalFormat == GL_RGBA &&
12982e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger      ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
12992e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
13002e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
13012e2a9813355993ba79eeb8070391e45aabb84f94Roland Scheidegger       (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
1302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
130317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
130460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1305b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1306b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1307f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1308f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1309f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
131071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
131146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	    (srcType == GL_UNSIGNED_BYTE ||
131246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
131346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1314528de982f88bfc025425ce1188781a34f4d84f1fRoland Scheidegger	    can_swizzle(baseInternalFormat) &&
131571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
131646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
131771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
131871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
1319528de982f88bfc025425ce1188781a34f4d84f1fRoland Scheidegger      /* dstmap - how to swizzle from RGBA to dst format:
132071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
132146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      if (dstFormat == &_mesa_texformat_rgba8888) {
132246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[3] = 0;
132346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[2] = 1;
132446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[1] = 2;
132546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[0] = 3;
132646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      }
132746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      else {
132846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[3] = 3;
132946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[2] = 2;
133046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[1] = 1;
133146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[0] = 0;
133246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      }
133371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
133471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
133571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
133646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell				srcType,
1337528de982f88bfc025425ce1188781a34f4d84f1fRoland Scheidegger				baseInternalFormat,
133871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
133971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1340528de982f88bfc025425ce1188781a34f4d84f1fRoland Scheidegger				dstRowStride, dstImageOffsets,
134171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
134271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
134371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
1344f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1345f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
13468f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1347f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1348f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1349f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1350f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1351f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1352f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1353f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1354f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1355f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1356f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1357f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1358b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1359b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1360b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1361b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1362f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1363f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLuint *dstUI = (GLuint *) dstRow;
1364f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_rgba8888) {
1365f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1366f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1367f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1368f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]),
1369f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[ACOMP]) );
1370f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1371f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1373f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1374f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1375f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1376f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1377f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]),
1378f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[ACOMP]) );
1379f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1380f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1381a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1382a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1383a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1384a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1385a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1386a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1387a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1388a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1389a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1390a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1391a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1392b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb8888(TEXSTORE_PARAMS)
1393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1394184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
1395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1396defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb8888 ||
1397defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb8888_rev);
1398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 4);
1399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1402defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888 &&
1403f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1404f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1405f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1406defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1407defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (little endian) */
140817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
140960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1410b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1411b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1415defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   else if (!ctx->_ImageTransferState &&
1416a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1417defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb8888_rev &&
1418a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGBA &&
1419a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_BGRA &&
1420a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1421defb035b6cf03c555318d9dd48864242ed036f39Brian Paul        srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1422defb035b6cf03c555318d9dd48864242ed036f39Brian Paul      /* simple memcpy path (big endian) */
142317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
142460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1425b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1426b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1427a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1428a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1429a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
143071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
143171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
143271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
143371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGB &&
14340c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell	    (baseInternalFormat == GL_RGBA ||
14350c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell	     baseInternalFormat == GL_RGB) &&
143671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
143771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
143871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      int img, row, col;
143971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
144071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
144171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
144271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
144371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1444b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1445b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1446b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1447b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
144871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
144971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
145071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 3 + BCOMP];
145171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 3 + GCOMP];
145271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 3 + RCOMP];
145371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = 0xff;
145471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
145571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
145671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
145771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
145871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
145971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
146071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
146171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            !srcPacking->SwapBytes &&
146271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    dstFormat == &_mesa_texformat_argb8888 &&
146371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcFormat == GL_RGBA &&
14640c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell	    baseInternalFormat == GL_RGBA &&
1465ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            (srcType == GL_UNSIGNED_BYTE && littleEndian)) {
1466b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
1467ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      /* For some reason, streaming copies to write-combined regions
1468ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * are extremely sensitive to the characteristics of how the
1469ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * source data is retrieved.  By reordering the source reads to
1470ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * be in-order, the speed of this operation increases by half.
1471ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       * Strangely the same isn't required for the RGB path, above.
1472ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul       */
1473ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      for (img = 0; img < srcDepth; img++) {
1474ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1475ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                                                 srcWidth, srcFormat, srcType);
1476ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1477ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1478b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1479b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1480b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1481b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1482b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul
1483ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         for (row = 0; row < srcHeight; row++) {
1484ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            for (col = 0; col < srcWidth; col++) {
1485ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul               *(GLuint *)(dstRow + col * 4)  = (srcRow[col * 4 + RCOMP] << 16 |
1486ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + GCOMP] << 8 |
1487ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + BCOMP] << 0 |
1488ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul						 srcRow[col * 4 + ACOMP] << 24);
1489ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            }
1490ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            dstRow += dstRowStride;
1491ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcRow += srcRowStride;
1492ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul         }
1493ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul      }
1494ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   }
1495ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul   else if (!ctx->_ImageTransferState &&
1496ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            !srcPacking->SwapBytes &&
1497ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul	    dstFormat == &_mesa_texformat_argb8888 &&
1498ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul            srcFormat == GL_RGBA &&
14990c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell	    baseInternalFormat == GL_RGBA &&
150071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcType == GL_UNSIGNED_BYTE) {
150171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
1502b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
150371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      for (img = 0; img < srcDepth; img++) {
150471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
150571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                                                 srcWidth, srcFormat, srcType);
150671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
150771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1508b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1509b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1510b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1511b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
151271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         for (row = 0; row < srcHeight; row++) {
151371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            for (col = 0; col < srcWidth; col++) {
151471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 0] = srcRow[col * 4 + BCOMP];
151571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 1] = srcRow[col * 4 + GCOMP];
151671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 2] = srcRow[col * 4 + RCOMP];
151771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell               dstRow[col * 4 + 3] = srcRow[col * 4 + ACOMP];
151871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            }
151971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            dstRow += dstRowStride;
152071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell            srcRow += srcRowStride;
152171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell         }
152271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      }
152371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
152471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   else if (!ctx->_ImageTransferState &&
152546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	    (srcType == GL_UNSIGNED_BYTE ||
152646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8 ||
152746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	     srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
15280c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell	    can_swizzle(baseInternalFormat) &&
152971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell	    can_swizzle(srcFormat)) {
153071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
153171699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      GLubyte dstmap[4];
153271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
15330c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
153471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell       */
153546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      if (dstFormat == &_mesa_texformat_argb8888) {
153646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[3] = 3;		/* alpha */
153746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[2] = 0;		/* red */
153846c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[1] = 1;		/* green */
153946c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[0] = 2;		/* blue */
154046c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      }
154146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      else {
154246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 assert(dstFormat == &_mesa_texformat_argb8888_rev);
154346c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[3] = 2;
154446c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[2] = 1;
154546c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[1] = 0;
154646c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell	 dstmap[0] = 3;
154746c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell      }
154871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell
154971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
155071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcFormat,
155146c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell				srcType,
155246c3bd29be4970a8b0c1c358aae0f1d7c05bc9f4Keith Whitwell
15530c9259f3b95615ceda134bd7074d871cd0186c89Keith Whitwell				baseInternalFormat,
155471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstmap, 4,
155571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
1556b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul				dstRowStride,
1557b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                dstImageOffsets,
155871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
155971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell				srcPacking);
156071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   }
1561a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1562a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1563a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1564a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1565a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1566a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1567a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1568a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
1569a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *src = tempImage;
1570a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1571a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1572a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1573a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1574a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1575b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1576b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1577b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1578b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1579a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1580a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            GLuint *dstUI = (GLuint *) dstRow;
1581f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb8888) {
1582f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1583f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1584f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1585f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1586f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1587f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1588f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1589a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1590f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1591f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1592f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1593f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1594f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1595f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1596f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1597f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1598defb035b6cf03c555318d9dd48864242ed036f39Brian Paul            }
1599a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1600a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1601a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1602a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1603a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1604a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1605a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1606a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1607f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1608f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1609b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb888(TEXSTORE_PARAMS)
1610f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1611184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
1612f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1613f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb888);
1614f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 3);
1615f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1616f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1617f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
1619f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGR &&
1620f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1621f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1622f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
162317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
162460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1625b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1626b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1627f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1628f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1629f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1630f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else if (!ctx->_ImageTransferState &&
1631f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            !srcPacking->SwapBytes &&
1632f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcFormat == GL_RGBA &&
1633f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcType == GL_UNSIGNED_BYTE) {
1634a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract RGB from RGBA */
1635b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint img, row, col;
1636f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1637f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1638f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcFormat, srcType);
163960909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
164060909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1641b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1642b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1643b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1644b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1645f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1646f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1647f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1648f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1649f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1650f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1651f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1652f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            srcRow += srcRowStride;
1653f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1654f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1655f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
16563aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   else if (!ctx->_ImageTransferState &&
16573aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
16583aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(baseInternalFormat) &&
16593aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(srcFormat)) {
16603aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
16613aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte dstmap[4];
16623aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
16633aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
16643aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell       */
1665167ca59fe893a62e23e799f51608d18847dd590aKeith Whitwell      dstmap[0] = 2;
16663aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[1] = 1;
1667167ca59fe893a62e23e799f51608d18847dd590aKeith Whitwell      dstmap[2] = 0;
16683aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[3] = ONE;		/* ? */
16693aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
16703aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
16713aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcFormat,
16723aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcType,
16733aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				baseInternalFormat,
16743aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstmap, 3,
16753aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
16763aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstRowStride, dstImageOffsets,
16773aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
16783aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcPacking);
16793aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   }
1680f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1681f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
16828f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1683f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1684f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1685f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1686f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1687f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
16887c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1689f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1690f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1691f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1692f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1693f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1694b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1695b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1696b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1697b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1698f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1699f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#if 0
1700f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            if (littleEndian) {
1701f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1702f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1703f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1704f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1705f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1706f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1707f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1708f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            else {
1709f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               for (col = 0; col < srcWidth; col++) {
1710f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 0] = srcUB[BCOMP];
1711f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 1] = srcUB[GCOMP];
1712f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  dstRow[col * 3 + 2] = srcUB[RCOMP];
1713f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcUB += 3;
1714f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               }
1715f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1716f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#else
1717f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
1718f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1719f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1720f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1721f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
1722f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1723f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul#endif
1724f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
1725f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
1726f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
1727f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
1728f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1729f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
1730f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
1731f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1732f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1733f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1734b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_bgr888(TEXSTORE_PARAMS)
1735a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul{
1736184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
1737a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1738a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat == &_mesa_texformat_bgr888);
1739a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   ASSERT(dstFormat->TexelBytes == 3);
1740a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1741a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   if (!ctx->_ImageTransferState &&
1742a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       !srcPacking->SwapBytes &&
1743a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       baseInternalFormat == GL_RGB &&
1744a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcFormat == GL_RGB &&
1745a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       srcType == GL_UNSIGNED_BYTE &&
1746a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul       littleEndian) {
1747a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* simple memcpy path */
174817bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
174960909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1750b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1751b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1752a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1753a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                     srcAddr, srcPacking);
1754a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1755a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else if (!ctx->_ImageTransferState &&
1756a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            !srcPacking->SwapBytes &&
1757a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcFormat == GL_RGBA &&
1758a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcType == GL_UNSIGNED_BYTE) {
1759a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* extract BGR from RGBA */
1760a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      int img, row, col;
1761a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1762a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         const GLint srcRowStride = _mesa_image_row_stride(srcPacking,
1763a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcFormat, srcType);
176460909388ab136d849d99eab49e782a53772a618fBrian Paul         GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
176560909388ab136d849d99eab49e782a53772a618fBrian Paul                  srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1766b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1767b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1768b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1769b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1770a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1771a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1772a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1773a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1774a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1775a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1776a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1777a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            srcRow += srcRowStride;
1778a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1779a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1780a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
17813aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   else if (!ctx->_ImageTransferState &&
17823aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
17833aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(baseInternalFormat) &&
17843aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(srcFormat)) {
17853aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
17863aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte dstmap[4];
17873aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
17883aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
17893aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell       */
1790167ca59fe893a62e23e799f51608d18847dd590aKeith Whitwell      dstmap[0] = 0;
17913aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[1] = 1;
1792167ca59fe893a62e23e799f51608d18847dd590aKeith Whitwell      dstmap[2] = 2;
17933aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[3] = ONE;		/* ? */
17943aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
17953aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
17963aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcFormat,
17973aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcType,
17983aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				baseInternalFormat,
17993aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstmap, 3,
18003aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
18013aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstRowStride, dstImageOffsets,
18023aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
18033aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcPacking);
18043aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   }
1805a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   else {
1806a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      /* general path */
1807a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1808a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 baseInternalFormat,
1809a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 dstFormat->BaseFormat,
1810a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcWidth, srcHeight, srcDepth,
1811a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcFormat, srcType, srcAddr,
1812a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul                                                 srcPacking);
18137c544d36850c6e3627adbbd66df9b12bbe0f185bBrian Paul      const GLchan *src = (const GLchan *) tempImage;
1814a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      GLint img, row, col;
1815a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      if (!tempImage)
1816a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         return GL_FALSE;
1817a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1818a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      for (img = 0; img < srcDepth; img++) {
1819b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1820b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1821b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1822b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1823a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         for (row = 0; row < srcHeight; row++) {
1824a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            for (col = 0; col < srcWidth; col++) {
1825a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1826a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1827a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1828a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul               src += 3;
1829a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1830a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1831a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1832a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1833a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1834a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1835a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1836a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1837a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1838a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1839a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1840b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb4444(TEXSTORE_PARAMS)
1841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1842defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb4444 ||
1843defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb4444_rev);
1844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1848defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb4444 &&
1849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1851defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
185317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
185460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1855b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1856b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
18628f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
1869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1874b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1875b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1876b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1877b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1880f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb4444) {
1881f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1882f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1883f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1884f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1885f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1886f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1887f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1889f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1890f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1891f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1892f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1893f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1894f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1895f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1896f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1897a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1898a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1899a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1900a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1901a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1902a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1903a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1904a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1905a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1906a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1907defb035b6cf03c555318d9dd48864242ed036f39Brian Paul
1908a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
1909b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_argb1555(TEXSTORE_PARAMS)
1910f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1911defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_argb1555 ||
1912defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_argb1555_rev);
1913f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1914f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1915f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1916f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1917defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_argb1555 &&
1918f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGBA &&
1919f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_BGRA &&
1920defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1921f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
192217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
192360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1924b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1925b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1926f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1927f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1928f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
1929f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
1930f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
19318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1932f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
1933f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
1934f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
1935f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
1936f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
1937f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src =tempImage;
1938f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
1939f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
1940f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
1941f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1942f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
1943b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
1944b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
1945b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
1946b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
1947f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
1948f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
1949f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_argb1555) {
1950f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1951f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1952f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[RCOMP]),
1953f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[GCOMP]),
1954f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                CHAN_TO_UBYTE(src[BCOMP]) );
1955f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1956f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1957f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
1958f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
1959f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
1960f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
1961f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[RCOMP]),
1962f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[GCOMP]),
1963f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                    CHAN_TO_UBYTE(src[BCOMP]) );
1964f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  src += 4;
1965f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
1966a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
1967a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
1968a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
1969a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
1970a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
1971a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
1972a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
1973a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
1974a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
1975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
1977b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_al88(TEXSTORE_PARAMS)
1978f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
1979184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
1980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1981defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   ASSERT(dstFormat == &_mesa_texformat_al88 ||
1982defb035b6cf03c555318d9dd48864242ed036f39Brian Paul          dstFormat == &_mesa_texformat_al88_rev);
1983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
1984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
1985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
1986f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
1987defb035b6cf03c555318d9dd48864242ed036f39Brian Paul       dstFormat == &_mesa_texformat_al88 &&
1988f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_LUMINANCE_ALPHA &&
1989f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_LUMINANCE_ALPHA &&
1990f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE &&
1991f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       littleEndian) {
1992f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
199317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
199460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1995b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
1996b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
1997f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1998f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
1999f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
20003aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   else if (!ctx->_ImageTransferState &&
20013aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
20023aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(baseInternalFormat) &&
20033aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(srcFormat)) {
20043aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
20053aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte dstmap[4];
20063aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
20073aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
20083aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell       */
20093aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      if (dstFormat == &_mesa_texformat_al88) {
20103aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[0] = 0;
20113aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[1] = 3;
20123aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      }
20133aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      else {
20143aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[0] = 3;
20153aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[1] = 0;
20163aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      }
20173aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[2] = ZERO;		/* ? */
20183aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[3] = ONE;		/* ? */
20193aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
20203aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
20213aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcFormat,
20223aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcType,
20233aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				baseInternalFormat,
20243aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstmap, 2,
20253aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
20263aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstRowStride, dstImageOffsets,
20273aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
20283aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcPacking);
20293aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   }
2030f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2031f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
20328f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2033f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2034f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2035f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2036f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2037f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2038f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
2039f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
2040f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2043f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2044b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2045b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2046b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2047b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLushort *dstUS = (GLushort *) dstRow;
2050f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            if (dstFormat == &_mesa_texformat_al88) {
2051f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
2052f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
2053f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
2054f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                             CHAN_TO_UBYTE(src[0]) );
2055f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
2056f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
2057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2058f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul            else {
2059f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               for (col = 0; col < srcWidth; col++) {
2060f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                  /* src[0] is luminance, src[1] is alpha */
2061f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
2062f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                                                 CHAN_TO_UBYTE(src[0]) );
2063f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul                 src += 2;
2064f252f64430ccb957698fcf85e84c9d64008147ebBrian Paul               }
2065a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            }
2066a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul            dstRow += dstRowStride;
2067a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul         }
2068a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      }
2069a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul      _mesa_free((void *) tempImage);
2070a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   }
2071a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   return GL_TRUE;
2072a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul}
2073a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
2074a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul
2075a156b49800c1419785d0709b78ef0d35e6dab5dfBrian PaulGLboolean
2076b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgb332(TEXSTORE_PARAMS)
2077f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2078f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgb332);
2079f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
2080f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2081f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2082f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2083f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == GL_RGB &&
2084f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2085f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
208617bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
208760909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2088b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2089b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2090f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2091f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2092f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2093f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
20958f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2098f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
2102f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
2103f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2107b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2108b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2109b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2110b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2111f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2112f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
2113f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
2114f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[GCOMP]),
2115f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                             CHAN_TO_UBYTE(src[BCOMP]) );
2116f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               src += 3;
2117f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2118f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2119f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2120f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2121f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2122f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2124f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2125f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2126f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2127f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2128f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2129f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2130f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2131b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_a8(TEXSTORE_PARAMS)
2132f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2133f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_a8 ||
2134f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_l8 ||
2135f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_i8);
2136f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
2137f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2138f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2139f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2140f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2141f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
2142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
214317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
214460909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2145b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2146b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
21503aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   else if (!ctx->_ImageTransferState &&
21513aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    srcType == GL_UNSIGNED_BYTE &&
21523aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(baseInternalFormat) &&
21533aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	    can_swizzle(srcFormat)) {
21543aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
21553aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      GLubyte dstmap[4];
21563aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
21573aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      /* dstmap - how to swizzle from RGBA to dst format:
21583aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell       */
21593aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      if (dstFormat == &_mesa_texformat_a8) {
21603aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[0] = 3;
21613aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      }
21623aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      else {
21633aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell	 dstmap[0] = 0;
21643aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      }
21653aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[1] = ZERO;		/* ? */
21663aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[2] = ZERO;		/* ? */
21673aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      dstmap[3] = ONE;		/* ? */
21683aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell
21693aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell      _mesa_swizzle_ubyte_image(ctx, dims,
21703aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcFormat,
21713aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcType,
21723aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				baseInternalFormat,
21733aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstmap, 1,
21743aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstAddr, dstXoffset, dstYoffset, dstZoffset,
21753aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				dstRowStride, dstImageOffsets,
21763aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcWidth, srcHeight, srcDepth, srcAddr,
21773aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell				srcPacking);
21783aea82b396387bf3835f91bcc9121e02274c4c04Keith Whitwell   }
2179f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2180f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
21818f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2182f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2183f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2184f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2185f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2186f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2187f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLchan *src = tempImage;
2188f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row, col;
2189f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2190f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2191f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2192f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2193b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2194b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2195b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2196b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2198f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (col = 0; col < srcWidth; col++) {
2199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstRow[col] = CHAN_TO_UBYTE(src[col]);
2200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2201f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth;
2203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2205f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2208f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2212f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2213b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_ci8(TEXSTORE_PARAMS)
2214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2215a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) dims; (void) baseInternalFormat;
2216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_ci8);
2217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 1);
2218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_COLOR_INDEX);
2219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2220f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2221f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2222f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcFormat == GL_COLOR_INDEX &&
2223f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_UNSIGNED_BYTE) {
2224f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
222517bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
222660909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2227b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2228b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2229f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2230f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2231f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2232f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2233f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2234f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2235f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2236b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2237b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2238b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2239b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2240f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
224160909388ab136d849d99eab49e782a53772a618fBrian Paul            const GLvoid *src = _mesa_image_address(dims, srcPacking,
2242f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2243f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
2244f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    srcType, src, srcPacking,
2245f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                    ctx->_ImageTransferState);
2246f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2247f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2248f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2249f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2250f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2251f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2252f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2253f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2254f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2255f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_rev.
2256f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2257f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2258b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2259f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2260184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
2261a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx; (void) dims; (void) baseInternalFormat;
2262f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2263f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((dstFormat == &_mesa_texformat_ycbcr) ||
2264f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (dstFormat == &_mesa_texformat_ycbcr_rev));
2265f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == 2);
2266f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2267f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(srcFormat == GL_YCBCR_MESA);
2268f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2269f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2270f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2271f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2272f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* always just memcpy since no pixel transfer ops apply */
227317bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell   memcpy_texture(ctx, dims,
227460909388ab136d849d99eab49e782a53772a618fBrian Paul                  dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2275b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                  dstRowStride,
2276b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                  dstImageOffsets,
2277f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2278f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                  srcAddr, srcPacking);
2279f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2280f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* Check if we need byte swapping */
2281f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   /* XXX the logic here _might_ be wrong */
2282f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (srcPacking->SwapBytes ^
2283f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2284f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       (dstFormat == &_mesa_texformat_ycbcr_rev) ^
2285f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !littleEndian) {
2286f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2287f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2288b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2289b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2290b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2291b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2292f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2293b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            _mesa_swap2((GLushort *) dstRow, srcWidth);
2294b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride;
2295f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2296f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2297f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2298f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2299f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2300f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2301f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2302f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2303184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul/**
2304184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul * Store a combined depth/stencil texture image.
2305184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul */
2306184a9707227ab024d65d352fe7c09b3e287348e9Brian PaulGLboolean
2307b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2308184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul{
2309184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(dstFormat == &_mesa_texformat_z24_s8);
2310184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT);
2311184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   ASSERT(srcType == GL_UNSIGNED_INT_24_8_EXT);
2312184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2313184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   if (!ctx->_ImageTransferState &&
2314184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul       !srcPacking->SwapBytes) {
2315ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* simple path */
2316184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul      memcpy_texture(ctx, dims,
2317184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2318b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2319b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2320184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2321184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     srcAddr, srcPacking);
2322184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
2323184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   else {
2324ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      /* general path */
2325ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      const GLint srcRowStride
2326ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2327ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         / sizeof(GLuint);
2328ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      GLint img, row;
2329ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
2330ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      for (img = 0; img < srcDepth; img++) {
2331b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLuint *dstRow = (GLuint *) dstAddr
2332b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img]
2333b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride / sizeof(GLuint)
2334b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset;
2335ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         const GLuint *src
2336ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2337ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcWidth, srcHeight,
2338ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   srcFormat, srcType,
2339ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                                   img, 0, 0);
2340ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         for (row = 0; row < srcHeight; row++) {
2341ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLubyte stencil[MAX_WIDTH];
2342ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            GLint i;
2343ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* the 24 depth bits will be in the high position: */
2344ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_depth_span(ctx, srcWidth,
2345ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    GL_UNSIGNED_INT, /* dst type */
2346b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                    dstRow, /* dst addr */
2347ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    (GLfloat) 0xffffff, /* depthScale */
2348ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                    srcType, src, srcPacking);
2349ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* get the 8-bit stencil values */
2350ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            _mesa_unpack_stencil_span(ctx, srcWidth,
2351ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      GL_UNSIGNED_BYTE, /* dst type */
2352ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      stencil, /* dst addr */
2353ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      srcType, src, srcPacking,
2354ef8653a83800bc4b8e116e03ad52604097224378Brian Paul                                      ctx->_ImageTransferState);
2355ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            /* merge stencil values into depth values */
2356ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            for (i = 0; i < srcWidth; i++)
2357b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul               dstRow[i] |= stencil[i];
2358ef8653a83800bc4b8e116e03ad52604097224378Brian Paul
2359ef8653a83800bc4b8e116e03ad52604097224378Brian Paul            src += srcRowStride;
2360b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride / sizeof(GLuint);
2361ef8653a83800bc4b8e116e03ad52604097224378Brian Paul         }
2362ef8653a83800bc4b8e116e03ad52604097224378Brian Paul      }
2363184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   }
2364184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul   return GL_TRUE;
2365184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul}
2366184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2367184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul
2368f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2369f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2370f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * Store an image in any of the formats:
2371f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgba_float32
2372f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_rgb_float32
2373f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_alpha_float32
2374f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_float32
2375f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_luminance_alpha_float32
2376f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul *   _mesa_texformat_intensity_float32
2377f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2378f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2379b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2380f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2381e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2382f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2383f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float32 ||
2384f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float32 ||
2385f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float32 ||
2386f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float32 ||
2387f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float32 ||
2388f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float32);
2389f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2390f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2391f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2392f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2393f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2394f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2395f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLfloat));
2396f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2397f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2398f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2399f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2400f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_FLOAT) {
2401f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
240217bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
240360909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2404b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2405b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2406f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2407f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2408f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2409f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2410f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2411f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2412f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2413f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2414f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2415f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2416f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2417b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLfloat *srcRow = tempImage;
24189c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      GLint bytesPerRow;
2419f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2420f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2421f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2422f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
24239c1b13ff6a2fb873cada61271f382a912ad99631Brian Paul      bytesPerRow = srcWidth * components * sizeof(GLfloat);
2424f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2425b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2426b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2427b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2428b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2429f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2430b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            _mesa_memcpy(dstRow, srcRow, bytesPerRow);
2431b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            dstRow += dstRowStride;
2432b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            srcRow += srcWidth * components;
2433f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2434f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2435f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2436f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2437f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2438f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2439f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2440f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2441f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2442f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
2443f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * As above, but store 16-bit floats.
2444f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul */
2445f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian PaulGLboolean
2446b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul_mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2447f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul{
2448e5b6eee15d4ca3feff8c2759595b1327afa584c3Brian Paul   const GLint components = _mesa_components_in_format(dstFormat->BaseFormat);
2449f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2450f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat == &_mesa_texformat_rgba_float16 ||
2451f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_rgb_float16 ||
2452f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_alpha_float16 ||
2453f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_float16 ||
2454f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_luminance_alpha_float16 ||
2455f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          dstFormat == &_mesa_texformat_intensity_float16);
2456f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(baseInternalFormat == GL_RGBA ||
2457f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_RGB ||
2458f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_ALPHA ||
2459f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE ||
2460f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_LUMINANCE_ALPHA ||
2461f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul          baseInternalFormat == GL_INTENSITY);
2462f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   ASSERT(dstFormat->TexelBytes == components * sizeof(GLhalfARB));
2463f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2464f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!ctx->_ImageTransferState &&
2465f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       !srcPacking->SwapBytes &&
2466f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       baseInternalFormat == srcFormat &&
2467f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul       srcType == GL_HALF_FLOAT_ARB) {
2468f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* simple memcpy path */
246917bcf9f816db3098db42acd7f0672f64554dd6a0Keith Whitwell      memcpy_texture(ctx, dims,
247060909388ab136d849d99eab49e782a53772a618fBrian Paul                     dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2471b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstRowStride,
2472b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                     dstImageOffsets,
2473f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2474f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                     srcAddr, srcPacking);
2475f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2476f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   else {
2477f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      /* general path */
2478f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2479f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 baseInternalFormat,
2480f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 dstFormat->BaseFormat,
2481f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcWidth, srcHeight, srcDepth,
2482f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcFormat, srcType, srcAddr,
2483f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                 srcPacking);
2484f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      const GLfloat *src = tempImage;
2485f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLint img, row;
2486f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!tempImage)
2487f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         return GL_FALSE;
2488f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2489f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      for (img = 0; img < srcDepth; img++) {
2490b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         GLubyte *dstRow = (GLubyte *) dstAddr
2491b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstImageOffsets[dstZoffset + img] * dstFormat->TexelBytes
2492b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstYoffset * dstRowStride
2493b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul            + dstXoffset * dstFormat->TexelBytes;
2494f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (row = 0; row < srcHeight; row++) {
2495f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2496f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLint i;
2497f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (i = 0; i < srcWidth * components; i++) {
2498f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dstTexel[i] = _mesa_float_to_half(src[i]);
2499f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
2500f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dstRow += dstRowStride;
2501f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            src += srcWidth * components;
2502f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
2503f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2504f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2505f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      _mesa_free((void *) tempImage);
2506f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2507f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   return GL_TRUE;
2508f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul}
2509f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
2510f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
25118d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul#if FEATURE_EXT_texture_sRGB
25128d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
25138d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_srgb8(TEXSTORE_PARAMS)
25148d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
2515184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
251646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   const struct gl_texture_format *newDstFormat;
251746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   StoreTexImageFunc store;
251846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   GLboolean k;
251946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
252046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   ASSERT(dstFormat == &_mesa_texformat_srgb8);
252146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
252246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   /* reuse normal rgb texstore code */
252346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   if (littleEndian) {
252446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_bgr888;
252546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      store = _mesa_texstore_bgr888;
252646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   }
252746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   else {
252846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_rgb888;
252946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      store = _mesa_texstore_rgb888;
253046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   }
253146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
253246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   k = store(ctx, dims, baseInternalFormat,
253346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             newDstFormat, dstAddr,
253446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             dstXoffset, dstYoffset, dstZoffset,
253546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             dstRowStride, dstImageOffsets,
253646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             srcWidth, srcHeight, srcDepth,
253746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             srcFormat, srcType,
253846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul             srcAddr, srcPacking);
253946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   return k;
25408d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
25418d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
254254e15d65858c1d1eeea7291059766686cf2e1671Brian Paul
25438d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
25448d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_srgba8(TEXSTORE_PARAMS)
25458d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
2546184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
254746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   const struct gl_texture_format *newDstFormat;
254846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   GLboolean k;
254946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
255046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   ASSERT(dstFormat == &_mesa_texformat_srgba8);
255146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
255246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   /* reuse normal rgba texstore code */
255346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   if (littleEndian)
255446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_rgba8888_rev;
255546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   else
255646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_rgba8888;
255746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
255846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
255946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               newDstFormat, dstAddr,
256046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               dstXoffset, dstYoffset, dstZoffset,
256146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               dstRowStride, dstImageOffsets,
256246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               srcWidth, srcHeight, srcDepth,
256346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               srcFormat, srcType,
256446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                               srcAddr, srcPacking);
256546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   return k;
25668d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
25678d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
256854e15d65858c1d1eeea7291059766686cf2e1671Brian Paul
25698d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
25708d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_sl8(TEXSTORE_PARAMS)
25718d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
257246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   const struct gl_texture_format *newDstFormat;
257346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   GLboolean k;
257446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
257546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   ASSERT(dstFormat == &_mesa_texformat_sl8);
257646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
257746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   newDstFormat = &_mesa_texformat_l8;
257846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
257954e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   /* _mesa_textore_a8 handles luminance8 too */
258054e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
258154e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         newDstFormat, dstAddr,
258254e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         dstXoffset, dstYoffset, dstZoffset,
258354e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         dstRowStride, dstImageOffsets,
258454e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         srcWidth, srcHeight, srcDepth,
258554e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         srcFormat, srcType,
258654e15d65858c1d1eeea7291059766686cf2e1671Brian Paul                         srcAddr, srcPacking);
258746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   return k;
25888d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
25898d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
259054e15d65858c1d1eeea7291059766686cf2e1671Brian Paul
25918d214bc8044e5027e3fa9302b259d0c557270b00Brian PaulGLboolean
25928d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul_mesa_texstore_sla8(TEXSTORE_PARAMS)
25938d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul{
2594184b5d89380e18008d64adfe1756dca9736426f2Brian Paul   const GLboolean littleEndian = _mesa_little_endian();
259546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   const struct gl_texture_format *newDstFormat;
259646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   GLboolean k;
259746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
259846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   ASSERT(dstFormat == &_mesa_texformat_sla8);
259946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
260046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   /* reuse normal luminance/alpha texstore code */
260146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   if (littleEndian)
260246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_al88;
260346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   else
260446f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul      newDstFormat = &_mesa_texformat_al88_rev;
260546f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul
260646f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
260746f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           newDstFormat, dstAddr,
260846f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           dstXoffset, dstYoffset, dstZoffset,
260946f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           dstRowStride, dstImageOffsets,
261046f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           srcWidth, srcHeight, srcDepth,
261146f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           srcFormat, srcType,
261246f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul                           srcAddr, srcPacking);
261346f20579a28ac97dd6fd9cc505301b0764eb011aBrian Paul   return k;
26148d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul}
26158d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
26168d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
26178d214bc8044e5027e3fa9302b259d0c557270b00Brian Paul
2618f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
26197a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2620c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a texture image.
2621c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2622c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
262371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
26247a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
262571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
262671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
262771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLsizei width, GLsizei height, GLsizei depth,
262871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    GLenum format, GLenum type, const GLvoid *pixels,
262971699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const struct gl_pixelstore_attrib *unpack,
263071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell			    const char *funcName)
26317a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2632c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2633c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
26347a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (unpack->BufferObj->Name == 0) {
26357a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* no PBO */
26367a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
26377a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
263860909388ab136d849d99eab49e782a53772a618fBrian Paul   if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
263960909388ab136d849d99eab49e782a53772a618fBrian Paul                                  format, type, pixels)) {
2640c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2641c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
26427a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2643c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2644a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2645a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                          GL_READ_ONLY_ARB, unpack->BufferObj);
2646c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2647c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2648c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2649c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2650c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2651c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
26527a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
26537a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
26547a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
26557a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul/**
2656c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Check if an unpack PBO is active prior to fetching a compressed texture
2657c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * image.
2658c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * If so, do bounds checking and map the buffer into main memory.
2659c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * Any errors detected will be recorded.
266071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell * The caller _must_ call _mesa_unmap_teximage_pbo() too!
26617a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul */
266271699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellconst GLvoid *
266371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell_mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
2664c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 GLsizei imageSize, const GLvoid *pixels,
2665c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const struct gl_pixelstore_attrib *packing,
2666c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                                 const char *funcName)
26677a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul{
2668c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   GLubyte *buf;
2669c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
26707a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (packing->BufferObj->Name == 0) {
26717a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      /* not using a PBO - return pointer unchanged */
26727a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return pixels;
26737a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2674c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if ((const GLubyte *) pixels + imageSize >
2675f285f0d8f60adafdfba5c1f0563b81c68bd398d3Brian Paul       ((const GLubyte *) 0) + packing->BufferObj->Size) {
2676c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      /* out of bounds read! */
2677c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
2678c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
2679c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2680c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2681a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul   buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2682a760ccf6d8a1f94d505b4c211ff4c30bc1d325a8Brian Paul                                         GL_READ_ONLY_ARB, packing->BufferObj);
2683c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (!buf) {
2684c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
2685c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      return NULL;
26867a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   }
2687c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
2688c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   return ADD_POINTERS(buf, pixels);
26897a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul}
26907a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
26917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
2692c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul/**
2693c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * This function must be called after either of the validate_pbo_*_teximage()
2694c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul * functions.  It unmaps the PBO buffer if it was mapped earlier.
2695c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul */
269671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwellvoid
2697c039af165d5919008c6df599795951f85dea164dBrian Paul_mesa_unmap_teximage_pbo(GLcontext *ctx,
2698c039af165d5919008c6df599795951f85dea164dBrian Paul                         const struct gl_pixelstore_attrib *unpack)
2699c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul{
2700c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   if (unpack->BufferObj->Name) {
2701c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
2702c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul                              unpack->BufferObj);
2703c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul   }
2704c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul}
2705c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
270689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
2707da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2708da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2709da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a GLchan texel from a float-valued texture.
2710da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2711da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2712da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelFloatToChan( const struct gl_texture_image *texImage,
2713da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLchan *texelOut )
2714da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2715da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLfloat temp[4];
2716da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2717da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelf(texImage, i, j, k, temp);
27182742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
27192742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2720da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2721da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2722da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2723da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2724da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2725da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[0], temp[0]);
2726da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[1], temp[1]);
2727da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[2], temp[2]);
2728da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      UNCLAMPED_FLOAT_TO_CHAN(texelOut[3], temp[3]);
2729da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2730da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2731da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2732da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2733da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2734da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Adaptor for fetching a float texel from a GLchan-valued texture.
2735da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2736da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2737da9f65268db5d0468f91860d9ef9f244587c7f48Brian PaulFetchTexelChanToFloat( const struct gl_texture_image *texImage,
2738da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul                       GLint i, GLint j, GLint k, GLfloat *texelOut )
2739da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2740da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   GLchan temp[4];
2741da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2742da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   texImage->FetchTexelc(texImage, i, j, k, temp);
27432742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul   if (texImage->TexFormat->BaseFormat == GL_DEPTH_COMPONENT ||
27442742c4e4db63d61f585c014103eaeadffa8e0833Brian Paul       texImage->TexFormat->BaseFormat == GL_DEPTH_STENCIL_EXT) {
2745da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* just one channel */
2746da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2747da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2748da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else {
2749da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      /* four channels */
2750da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[0] = CHAN_TO_FLOAT(temp[0]);
2751da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[1] = CHAN_TO_FLOAT(temp[1]);
2752da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[2] = CHAN_TO_FLOAT(temp[2]);
2753da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texelOut[3] = CHAN_TO_FLOAT(temp[3]);
2754da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2755da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2756da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2757da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2758da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul/**
2759da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul * Initialize the texture image's FetchTexelc and FetchTexelf methods.
2760da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul */
2761da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulstatic void
2762da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paulset_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
2763da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul{
2764da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2765da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->TexFormat);
2766da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2767da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   switch (dims) {
2768da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 1:
2769da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel1D;
2770da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel1Df;
2771da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2772da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 2:
2773da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel2D;
2774da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel2Df;
2775da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2776da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   case 3:
2777da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = texImage->TexFormat->FetchTexel3D;
2778da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = texImage->TexFormat->FetchTexel3Df;
2779da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      break;
2780da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   default:
2781da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      ;
2782da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2783da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2784da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   /* now check if we need to use a float/chan adaptor */
2785da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   if (!texImage->FetchTexelc) {
2786da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelc = FetchTexelFloatToChan;
2787da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2788da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   else if (!texImage->FetchTexelf) {
2789da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul      texImage->FetchTexelf = FetchTexelChanToFloat;
2790da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   }
2791da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2792da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2793da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelc);
2794da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul   ASSERT(texImage->FetchTexelf);
2795da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul}
2796da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
2797da9f65268db5d0468f91860d9ef9f244587c7f48Brian Paul
27985999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
27995999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Choose the actual storage format for a new texture image.
28005999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
28015999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * Also set some other texImage fields related to texture compression, etc.
28025999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param ctx  rendering context
28035999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param texImage  the gl_texture_image
28045999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param dims  texture dimensions (1, 2 or 3)
28055999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param format  the user-specified format parameter
28065999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param type  the user-specified type parameter
28075999c5b620236fb6a996cf56759aec31f01c126bBrian Paul * \param internalFormat  the user-specified internal format hint
28085999c5b620236fb6a996cf56759aec31f01c126bBrian Paul */
28095999c5b620236fb6a996cf56759aec31f01c126bBrian Paulstatic void
28105999c5b620236fb6a996cf56759aec31f01c126bBrian Paulchoose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
28115999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLuint dims,
28125999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                      GLenum format, GLenum type, GLint internalFormat)
28135999c5b620236fb6a996cf56759aec31f01c126bBrian Paul{
2814c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(dims == 1 || dims == 2 || dims == 3);
2815c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(ctx->Driver.ChooseTextureFormat);
28165999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28175999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   texImage->TexFormat
28185999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
28195999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
2820c3c19be8e0d0b13916cc128cf3c8e839935c912aBrian Paul   ASSERT(texImage->TexFormat);
28215999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28225999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   set_fetch_functions(texImage, dims);
28235999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28245999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   if (texImage->TexFormat->TexelBytes == 0) {
28255999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* must be a compressed format */
28265999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_TRUE;
28275999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize =
28285999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ctx->Driver.CompressedTextureSize(ctx, texImage->Width,
28295999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->Height, texImage->Depth,
28305999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                           texImage->TexFormat->MesaFormat);
28315999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
28325999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   else {
28335999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      /* non-compressed format */
28345999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->IsCompressed = GL_FALSE;
28355999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      texImage->CompressedSize = 0;
28365999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   }
28375999c5b620236fb6a996cf56759aec31f01c126bBrian Paul}
28385999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28395999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28405999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
28417d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul/*
284289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage1D()
2843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul * and Driver.CopyTexImage1D().
28446b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
28458e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
28468e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
28478e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
28488e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
28498e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint border,
28508e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const GLvoid *pixels,
28518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
28528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
28538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
28548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
28558e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width;
2856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   GLint sizeInBytes;
2857a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
28588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
28608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 1, &postConvWidth, NULL);
28618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
28628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28635999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
28648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
28658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
286689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
286789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
286889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
2869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      sizeInBytes = postConvWidth * texImage->TexFormat->TexelBytes;
28704cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
28717d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
28727d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
28737d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
28747d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
28758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
2876e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
2877e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage1D");
28786b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
28796b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
28806b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
28816b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
288289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
28836b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
28846b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2885b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLint dstRowStride = 0;
2886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2888a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
2889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2892b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2893b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
2895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
2898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2900f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
290189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
290289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
290389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
290489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
290589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
29063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2907c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
290871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
29098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
29108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29126b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
291389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage2D()
291489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage2D().
29156b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul *
2916b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * This function is oriented toward storing images in main memory, rather
2917b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * than VRAM.  Device driver's can easily plug in their own replacement.
2918b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul *
2919b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * Note: width and height may be pre-convolved dimensions, but
2920b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * texImage->Width and texImage->Height will be post-convolved dimensions.
29218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
29228e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
29238e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
29248e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
29258e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint border,
29268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
29278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
29288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
29298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
29308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
29318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   GLint postConvWidth = width, postConvHeight = height;
2932e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
2933a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
29348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
29368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul      _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
29378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                         &postConvHeight);
29388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   }
29398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29405999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
29412c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
29422c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes   texelBytes = texImage->TexFormat->TexelBytes;
29438e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29448e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
294589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
294689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
294789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
294889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = postConvWidth * postConvHeight * texelBytes;
29494cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
29507d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
29517d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
29527d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
29537d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
29548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
295571699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
2956e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexImage2D");
29576b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
29586b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
29596b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
29606b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
296189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
29626b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
29636b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
2964b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
2965f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
2966f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
2967a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
29685999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
2969f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2970f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
2971b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
2972f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2973f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
2974a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
2975f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
2976f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
2977f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
2978b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
2979b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
2980f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
2981f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
2982f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
2983f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
2984f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
2985f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
2986f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
298789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
298889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
298989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
299089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
299189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
29923893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
2993c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
299471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
29958e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
29968e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29978e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29988e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
29996b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul/**
300089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexImage3D()
300189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexImage3D().
30026b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul * \sa _mesa_store_teximage2d()
30038e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
30048e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
30058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
30068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint internalFormat,
30078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLint width, GLint height, GLint depth, GLint border,
30088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       GLenum format, GLenum type, const void *pixels,
30098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       const struct gl_pixelstore_attrib *packing,
30108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_object *texObj,
30118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                       struct gl_texture_image *texImage)
30128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
3013e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul   GLint texelBytes, sizeInBytes;
3014a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
30158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30165999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
30172c3d34c905fa6b831a066afae83b938de05eb241Gareth Hughes
3018197c526d63e1d4ea96f29eece392cdc389770b38Brian Paul   texelBytes = texImage->TexFormat->TexelBytes;
30198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul   /* allocate memory */
302189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (texImage->IsCompressed)
302289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = texImage->CompressedSize;
302389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   else
302489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      sizeInBytes = width * height * depth * texelBytes;
30254cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
30267d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   if (!texImage->Data) {
30277d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
30287d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul      return;
30297d58f44f73be59bd3583e6dfeedf56c43f7fbd55Brian Paul   }
30308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3031e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3032e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing, "glTexImage3D");
30336b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   if (!pixels) {
30346b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul      /* Note: we check for a NULL image pointer here, _after_ we allocated
30356b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       * memory for the texture.  That's what the GL spec calls for.
30366b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul       */
303789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
30386b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   }
30396b6c96bdeb580052cb9fa3831f1cd574f0e85728Brian Paul   else {
3040b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
3041f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
3042f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
3043a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstRowStride
30445999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
3045f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3046f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
3047b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3048f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3049f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
3050a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
3051f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
3052f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
3053f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                0, 0, 0,  /* dstX/Y/Zoffset */
3054b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
3055b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
3056f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
3057f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
3058f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
3059f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3060f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3061f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
3062f3b85c983f469875ac76081a61539a6c7b26777cBrian Paul
306389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* GL_SGIS_generate_mipmap */
306489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
306589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_generate_mipmap(ctx, target,
306689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
306789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                            texObj);
30683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
3069c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
307071699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
30718e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
30728e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30738e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
30768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
307789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage1D()
307889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage1D().
30798e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
30808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
30818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
30828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint width,
30838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
30848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
30858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
30868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
30878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
3088b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
3089e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3090e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage1D");
30917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
30927a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
30937a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
3094f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
3095b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      const GLint dstRowStride = 0;
3096f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
3097f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
3098a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 1, texImage->_BaseFormat,
3099f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
3100f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
3101f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, 0, 0,  /* offsets */
3102b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
3103b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
3104f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, 1, 1,
3105f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
3106f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
3107f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
3108f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3109f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
31103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
31123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3113d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
3114d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
31153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
31163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
3117c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
311871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
31198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
31208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
31218e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
312289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3123f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul/**
312489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * This is the software fallback for Driver.TexSubImage2D()
312589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage2D().
31268e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
31278e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
31288e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
31298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset,
31308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height,
31318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
31328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
31338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
31348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
31358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
3136b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
313771699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3138e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        pixels, packing, "glTexSubImage2D");
31397a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!pixels)
31407a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
31417a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
3142f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
3143b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride = 0;
3144f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
3145f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
31465999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
3147f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
3148f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3149f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
3150b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3151f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3152f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
3153a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 2, texImage->_BaseFormat,
3154f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
3155f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
3156f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, 0,
3157b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
3158b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
3159f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, 1,
3160f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
3161f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
3162f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
3163f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3164f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
31653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
31663893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
31673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3168d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
3169d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
31703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
31713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
3172c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
317371699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
31748e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
31758e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
31768e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
31778e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
31788e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * This is the software fallback for Driver.TexSubImage3D().
317989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * and Driver.CopyTexSubImage3D().
31808e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
31818e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
31828e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
31838e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint xoffset, GLint yoffset, GLint zoffset,
31848e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLint width, GLint height, GLint depth,
31858e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          GLenum format, GLenum type, const void *pixels,
31868e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          const struct gl_pixelstore_attrib *packing,
31878e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_object *texObj,
31888e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                          struct gl_texture_image *texImage)
31898e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
3190b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
3191e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3192e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        type, pixels, packing,
3193e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                        "glTexSubImage3D");
3194f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   if (!pixels)
3195f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3196f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
3197f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   {
3198b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul      GLint dstRowStride;
3199f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      GLboolean success;
3200f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (texImage->IsCompressed) {
32015999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat,
3202f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                    texImage->Width);
3203f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3204f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      else {
3205b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul         dstRowStride = texImage->RowStride * texImage->TexFormat->TexelBytes;
3206f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3207f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      ASSERT(texImage->TexFormat->StoreImage);
3208a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      success = texImage->TexFormat->StoreImage(ctx, 3, texImage->_BaseFormat,
3209f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->TexFormat,
3210f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                texImage->Data,
3211f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                xoffset, yoffset, zoffset,
3212b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                dstRowStride,
3213b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul                                                texImage->ImageOffsets,
3214f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                width, height, depth,
3215f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                                                format, type, pixels, packing);
3216f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      if (!success) {
3217f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
3218f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3219f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   }
32208f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
32213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* GL_SGIS_generate_mipmap */
32223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
3223d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      _mesa_generate_mipmap(ctx, target,
3224d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
32253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                            texObj);
32263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
3227c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
322871699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, packing);
32298e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
32308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
32318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
32322aadbf41dfd4f63c6118d0ad2d8659d289cbe454Brian Paul/*
32338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage1D()
32348e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
32358e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
32368e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
32378e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
32388e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint border,
32398e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
32408e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
32418e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
32428e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
324389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
3244a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3245a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3246a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
3247a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) border;
3248a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3249a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3250a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
32518e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
32528e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
32538e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
32548e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
3255b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul/**
32568e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage2D()
32578e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
32588e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
32598e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
32608e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
32618e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint border,
32628e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
32638e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
32648e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
32658e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
3266a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) border;
3267a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul
326889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* This is pretty simple, basically just do a memcpy without worrying
326989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul    * about the usual image unpacking or image transfer operations.
32708e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul    */
327189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texObj);
327289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage);
327389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Width > 0);
327489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Height > 0);
327589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Depth == 1);
327689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
327789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
32785999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
327989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
328089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* allocate storage */
32814cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul   texImage->Data = _mesa_alloc_texmemory(imageSize);
328289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   if (!texImage->Data) {
328389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
328489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      return;
328589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
328689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3287e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3288e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
3289e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexImage2D");
32907a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
32917a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
32927a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
329389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* copy the data */
32944039cb8ca82d59451a6de8902fe35e693cdca3baBrian Paul   ASSERT(texImage->CompressedSize == (GLuint) imageSize);
329589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   MEMCPY(texImage->Data, data, imageSize);
32968f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
32978f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
32988f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
32998f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
33008f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
33018f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
33028f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
3303c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
330471699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
33058e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
33068e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
33078e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
33088e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
33098e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul/*
33108e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul * Fallback for Driver.CompressedTexImage3D()
33118e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul */
33128e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paulvoid
33138e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul_mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
33148e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint internalFormat,
33158e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint width, GLint height, GLint depth,
33168e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLint border,
33178e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  GLsizei imageSize, const GLvoid *data,
33188e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_object *texObj,
33198e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul                                  struct gl_texture_image *texImage)
33208e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul{
332189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* this space intentionally left blank */
3322a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3323a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3324a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) internalFormat;
3325a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
3326a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) border;
3327a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3328a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3329a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
33308e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul}
33318e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
33328e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
33338e39ad2cd67d49be40ff0822f3269affdf83d601Brian Paul
333489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
333589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage1D()
3336e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul */
3337e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paulvoid
333889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
333989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
334089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLsizei width,
334189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
334289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
334389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
334489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
3345e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul{
33465999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 1D texture formats yet */
3347a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3348a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3349a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) width;
3350a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
3351a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3352a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3353a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
3354e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul}
3355e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
3356e4276667dafc8de0c6e64af8300fc7598437de6eBrian Paul
335789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
335889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage2D()
335989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
336089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
336189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
336289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint level,
336389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLint xoffset, GLint yoffset,
336489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei width, GLsizei height,
336589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLenum format,
336689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     GLsizei imageSize, const GLvoid *data,
336789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_object *texObj,
336889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                     struct gl_texture_image *texImage)
336989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
337089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint bytesPerRow, destRowStride, srcRowStride;
337189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLint i, rows;
337289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   GLubyte *dest;
337389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   const GLubyte *src;
33745999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   const GLuint mesaFormat = texImage->TexFormat->MesaFormat;
33755999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
3376a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
337789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
337889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   /* these should have been caught sooner */
337989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((width & 3) == 0 || width == 2 || width == 1);
338089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((height & 3) == 0 || height == 2 || height == 1);
338189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((xoffset & 3) == 0);
338289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   ASSERT((yoffset & 3) == 0);
338389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
3384b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul   /* get pointer to src pixels (may be in a pbo which we'll map here) */
3385e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul   data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3386e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 &ctx->Unpack,
3387e4b2356c07d31fbeeabb13b2fb47db703b473080Brian Paul                                                 "glCompressedTexSubImage2D");
33887a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul   if (!data)
33897a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul      return;
33907a6b71ef2944bae1718e8167b2faaceb8422071cBrian Paul
33915999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   srcRowStride = _mesa_compressed_row_stride(mesaFormat, width);
339289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   src = (const GLubyte *) data;
339389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
33945999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   destRowStride = _mesa_compressed_row_stride(mesaFormat, texImage->Width);
339589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
3396a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                         texImage->TexFormat->MesaFormat,
3397f4418f4d1c6dfe06af760226c5303e653b25b879Brian Paul                                         texImage->Width,
3398a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                         (GLubyte *) texImage->Data);
339989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
340089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   bytesPerRow = srcRowStride;
340189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   rows = height / 4;
340289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
340389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   for (i = 0; i < rows; i++) {
340489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      MEMCPY(dest, src, bytesPerRow);
340589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      dest += destRowStride;
340689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      src += srcRowStride;
340789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
34088f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul
34098f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   /* GL_SGIS_generate_mipmap */
34108f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
34118f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul      _mesa_generate_mipmap(ctx, target,
34128f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            &ctx->Texture.Unit[ctx->Texture.CurrentUnit],
34138f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                            texObj);
34148f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul   }
3415c0ebc4931a003b7b14e92c3b537b6ba76259507cBrian Paul
341671699df7de8cc732caf6d4b8adb4ab2d1f0c7c1fKeith Whitwell   _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
341789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
341889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
341989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
342089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul/**
342189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul * Fallback for Driver.CompressedTexSubImage3D()
342289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul */
342389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paulvoid
342489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul_mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
342589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint level,
342689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLint xoffset, GLint yoffset, GLint zoffset,
342789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei width, GLsizei height, GLsizei depth,
342889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLenum format,
342989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                GLsizei imageSize, const GLvoid *data,
343089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_object *texObj,
343189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                                struct gl_texture_image *texImage)
343289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul{
34335999c5b620236fb6a996cf56759aec31f01c126bBrian Paul   /* there are no compressed 3D texture formats yet */
3434a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) ctx;
3435a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) target; (void) level;
3436a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) xoffset; (void) yoffset; (void) zoffset;
3437a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) width; (void) height; (void) depth;
3438a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) format;
3439a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) imageSize; (void) data;
3440a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texObj;
3441a6c423d95663cfd8601cf84e10e8e1b12fa6ef15Brian Paul   (void) texImage;
344289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul}
344389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
344489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
34453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul/*
34463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Average together two rows of a source image to produce a single new
34473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * row in the dest image.  It's legal for the two source rows to point
34489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * to the same data.  The source width must be equal to either the
34499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * dest width or two times the dest width.
34503893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
34513893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
34529228e17bb5bf219269daeed5cbfdd912c118e926Brian Pauldo_row(const struct gl_texture_format *format, GLint srcWidth,
34539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       const GLvoid *srcRowA, const GLvoid *srcRowB,
34549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul       GLint dstWidth, GLvoid *dstRow)
34553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
34569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint k0 = (srcWidth == dstWidth) ? 0 : 1;
34579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLuint colStride = (srcWidth == dstWidth) ? 1 : 2;
34589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
3459c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   /* This assertion is no longer valid with non-power-of-2 textures
34609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   assert(srcWidth == dstWidth || srcWidth == 2 * dstWidth);
3461c515f90ec3adca875e93b4a705e14f4a0a1661b4Brian Paul   */
34629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
34633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   switch (format->MesaFormat) {
34643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGBA:
34653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
34669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
34673893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[4] = (const GLchan (*)[4]) srcRowA;
34683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[4] = (const GLchan (*)[4]) srcRowB;
34693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[4] = (GLchan (*)[4]) dstRow;
34707c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
34719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
34729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3473f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
34749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3475f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
34769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3477f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
34789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3479f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
34803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
34813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
34823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
34833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_RGB:
34843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
34859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
34863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[3] = (const GLchan (*)[3]) srcRowA;
34873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[3] = (const GLchan (*)[3]) srcRowB;
34883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[3] = (GLchan (*)[3]) dstRow;
34897c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
34909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
34919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3492f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
34939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3494f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
34959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3496f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
34973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
34983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
34993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
35003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_ALPHA:
35013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE:
35023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_INTENSITY:
35033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
35049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
35053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowA = (const GLchan *) srcRowA;
35063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan *rowB = (const GLchan *) srcRowB;
35073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan *dst = (GLchan *) dstRow;
35087c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
35099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3510f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
35113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
35123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
35133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
35143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA:
35153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      {
35169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
35173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowA)[2] = (const GLchan (*)[2]) srcRowA;
35183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         const GLchan (*rowB)[2] = (const GLchan (*)[2]) srcRowB;
35193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         GLchan (*dst)[2] = (GLchan (*)[2]) dstRow;
35207c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
35219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
35229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3523f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
35249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3525f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
35263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         }
35273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
35283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
3529a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z32:
35308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
35319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
3532a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowA = (const GLuint *) srcRowA;
3533a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul         const GLuint *rowB = (const GLuint *) srcRowB;
35348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLfloat *dst = (GLfloat *) dstRow;
35357c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
35369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
3537a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul            dst[i] = rowA[j] / 4 + rowA[k] / 4 + rowB[j] / 4 + rowB[k] / 4;
35388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
35398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
35408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3541a9bcf751030895494fc098f8d0ff56b2496bd993Brian Paul   case MESA_FORMAT_Z16:
3542f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3543f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3544f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
3545f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
3546f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLushort *dst = (GLushort *) dstRow;
3547f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3548f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3549f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) / 4;
3550f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3551f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3552f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
35538bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* Begin hardware formats */
35548bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGBA8888:
3555defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGBA8888_REV:
35568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB8888:
3557defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB8888_REV:
355854e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#if FEATURE_EXT_texture_sRGB
355954e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   case MESA_FORMAT_SRGBA8:
356054e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#endif
35618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
35629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
35638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[4] = (const GLubyte (*)[4]) srcRowA;
35648bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[4] = (const GLubyte (*)[4]) srcRowB;
35658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[4] = (GLubyte (*)[4]) dstRow;
35667c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
35679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
35689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3569f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
35709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3571f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
35729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3573f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
35749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3575f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][3] + rowB[k][3]) / 4;
35768bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
35778bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
35788bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
35798bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB888:
3580a156b49800c1419785d0709b78ef0d35e6dab5dfBrian Paul   case MESA_FORMAT_BGR888:
358154e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#if FEATURE_EXT_texture_sRGB
358254e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   case MESA_FORMAT_SRGB8:
358354e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#endif
35848bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
35859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
35868bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[3] = (const GLubyte (*)[3]) srcRowA;
35878bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[3] = (const GLubyte (*)[3]) srcRowB;
35888bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[3] = (GLubyte (*)[3]) dstRow;
35897c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
35909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
35919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3592f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][0] + rowB[k][0]) / 4;
35939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3594f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][1] + rowB[k][1]) / 4;
35959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3596f431a3fb4dc1bf860203d79e54657e3a62bc50dfBrian Paul                         rowB[j][2] + rowB[k][2]) / 4;
35978bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
35988bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
35998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
36008bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB565:
3601defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_RGB565_REV:
36028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
36039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
36048bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
36058bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
36068bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
36077c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
36089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
36099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
36109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
36119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
36129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x1f;
36139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x3f;
36149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x3f;
36159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x3f;
36169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x3f;
36179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 11) & 0x1f;
36189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 11) & 0x1f;
36199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 11) & 0x1f;
36209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 11) & 0x1f;
362107d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
362207d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
362307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
36248bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 11) | (green << 5) | red;
36258bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
36268bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
36278bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
36288bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB4444:
3629defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB4444_REV:
36308bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
36319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
36328bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
36338bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
36348bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
36357c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
36369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
36379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0xf;
36389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0xf;
36399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0xf;
36409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
36419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 4) & 0xf;
36429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 4) & 0xf;
36439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 4) & 0xf;
36449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 4) & 0xf;
36459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 8) & 0xf;
36469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 8) & 0xf;
36479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 8) & 0xf;
36489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 8) & 0xf;
36499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 12) & 0xf;
36509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 12) & 0xf;
36519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 12) & 0xf;
36529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 12) & 0xf;
365307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
365407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
365507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
365607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
36578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 12) | (blue << 8) | (green << 4) | red;
36588bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
36598bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
36608bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
36618bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_ARGB1555:
3662defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_ARGB1555_REV: /* XXX broken? */
36638bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
36649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
36658bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowA = (const GLushort *) srcRowA;
36668bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLushort *rowB = (const GLushort *) srcRowB;
36678bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLushort *dst = (GLushort *) dstRow;
36687c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
36699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
36709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x1f;
36719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x1f;
36729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x1f;
36739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0xf;
36749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 5) & 0x1f;
36759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 5) & 0x1f;
36769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 5) & 0x1f;
36779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 5) & 0x1f;
36789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 10) & 0x1f;
36799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 10) & 0x1f;
36809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 10) & 0x1f;
36819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 10) & 0x1f;
36829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa0 = (rowA[j] >> 15) & 0x1;
36839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAa1 = (rowA[k] >> 15) & 0x1;
36849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa0 = (rowB[j] >> 15) & 0x1;
36859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBa1 = (rowB[k] >> 15) & 0x1;
368607d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
368707d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
368807d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
368907d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint alpha = (rowAa0 + rowAa1 + rowBa0 + rowBa1) >> 2;
36908bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (alpha << 15) | (blue << 10) | (green << 5) | red;
36918bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
36928bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
36938bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
36948bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_AL88:
3695defb035b6cf03c555318d9dd48864242ed036f39Brian Paul   case MESA_FORMAT_AL88_REV:
369654e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#if FEATURE_EXT_texture_sRGB
369754e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   case MESA_FORMAT_SLA8:
369854e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#endif
36998bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
37009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
37018bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowA)[2] = (const GLubyte (*)[2]) srcRowA;
37028bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte (*rowB)[2] = (const GLubyte (*)[2]) srcRowB;
37038bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte (*dst)[2] = (GLubyte (*)[2]) dstRow;
37047c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
37059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
37069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
37079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][0] + rowB[k][0]) >> 2;
37089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
37099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         rowB[j][1] + rowB[k][1]) >> 2;
37108bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
37118bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
37128bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
37138bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_RGB332:
37148bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
37159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
37168bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
37178bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
37188bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
37197c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
37209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
37219228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr0 = rowA[j] & 0x3;
37229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAr1 = rowA[k] & 0x3;
37239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr0 = rowB[j] & 0x3;
37249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBr1 = rowB[k] & 0x3;
37259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg0 = (rowA[j] >> 2) & 0x7;
37269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAg1 = (rowA[k] >> 2) & 0x7;
37279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg0 = (rowB[j] >> 2) & 0x7;
37289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBg1 = (rowB[k] >> 2) & 0x7;
37299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb0 = (rowA[j] >> 5) & 0x7;
37309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowAb1 = (rowA[k] >> 5) & 0x7;
37319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb0 = (rowB[j] >> 5) & 0x7;
37329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLint rowBb1 = (rowB[k] >> 5) & 0x7;
373307d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint red   = (rowAr0 + rowAr1 + rowBr0 + rowBr1) >> 2;
373407d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint green = (rowAg0 + rowAg1 + rowBg0 + rowBg1) >> 2;
373507d6a983595b7ee52c8448fc579d952ce36472b8Ian Romanick            const GLint blue  = (rowAb0 + rowAb1 + rowBb0 + rowBb1) >> 2;
37368bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul            dst[i] = (blue << 5) | (green << 2) | red;
37378bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
37388bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
37398bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
37408bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_A8:
37418bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_L8:
37428bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_I8:
37438bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   case MESA_FORMAT_CI8:
374454e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#if FEATURE_EXT_texture_sRGB
374554e15d65858c1d1eeea7291059766686cf2e1671Brian Paul   case MESA_FORMAT_SL8:
374654e15d65858c1d1eeea7291059766686cf2e1671Brian Paul#endif
37478bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      {
37489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         GLuint i, j, k;
37498bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowA = (const GLubyte *) srcRowA;
37508bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         const GLubyte *rowB = (const GLubyte *) srcRowB;
37518bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         GLubyte *dst = (GLubyte *) dstRow;
37527c4268176eaaeb45003db4d5042a518b84c9f6dcKarl Schultz         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
37539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul              i++, j += colStride, k += colStride) {
37549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) >> 2;
37558bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul         }
37568bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      }
37578bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul      return;
3758f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT32:
3759f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3760f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3761f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[4] = (const GLfloat (*)[4]) srcRowA;
3762f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[4] = (const GLfloat (*)[4]) srcRowB;
3763f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[4] = (GLfloat (*)[4]) dstRow;
3764f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3765f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3766f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3767f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3768f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3769f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3770f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3771f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3772f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][3] = (rowA[j][3] + rowA[k][3] +
3773f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][3] + rowB[k][3]) * 0.25F;
3774f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3775f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3776f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3777f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGBA_FLOAT16:
3778f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3779f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3780f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[4] = (const GLhalfARB (*)[4]) srcRowA;
3781f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[4] = (const GLhalfARB (*)[4]) srcRowB;
3782f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[4] = (GLhalfARB (*)[4]) dstRow;
3783f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3784f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3785f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 4; comp++) {
3786f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3787f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3788f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3789f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3790f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3791f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3792f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3793f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3794f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3795f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3796f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT32:
3797f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3798f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3799f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[3] = (const GLfloat (*)[3]) srcRowA;
3800f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[3] = (const GLfloat (*)[3]) srcRowB;
3801f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[3] = (GLfloat (*)[3]) dstRow;
3802f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3803f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3804f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3805f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3806f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3807f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3808f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][2] = (rowA[j][2] + rowA[k][2] +
3809f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][2] + rowB[k][2]) * 0.25F;
3810f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3811f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3812f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3813f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_RGB_FLOAT16:
3814f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3815f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3816f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[3] = (const GLhalfARB (*)[3]) srcRowA;
3817f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[3] = (const GLhalfARB (*)[3]) srcRowB;
3818f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[3] = (GLhalfARB (*)[3]) dstRow;
3819f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3820f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3821f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 3; comp++) {
3822f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3823f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3824f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3825f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3826f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3827f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3828f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3829f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3830f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3831f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3832f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
3833f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3834f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3835f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowA)[2] = (const GLfloat (*)[2]) srcRowA;
3836f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat (*rowB)[2] = (const GLfloat (*)[2]) srcRowB;
3837f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat (*dst)[2] = (GLfloat (*)[2]) dstRow;
3838f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3839f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3840f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][0] = (rowA[j][0] + rowA[k][0] +
3841f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][0] + rowB[k][0]) * 0.25F;
3842f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i][1] = (rowA[j][1] + rowA[k][1] +
3843f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul                         rowB[j][1] + rowB[k][1]) * 0.25F;
3844f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3845f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3846f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3847f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
3848f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3849f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k, comp;
3850f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowA)[2] = (const GLhalfARB (*)[2]) srcRowA;
3851f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB (*rowB)[2] = (const GLhalfARB (*)[2]) srcRowB;
3852f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB (*dst)[2] = (GLhalfARB (*)[2]) dstRow;
3853f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3854f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3855f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            for (comp = 0; comp < 2; comp++) {
3856f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               GLfloat aj, ak, bj, bk;
3857f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               aj = _mesa_half_to_float(rowA[j][comp]);
3858f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               ak = _mesa_half_to_float(rowA[k][comp]);
3859f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bj = _mesa_half_to_float(rowB[j][comp]);
3860f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               bk = _mesa_half_to_float(rowB[k][comp]);
3861f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul               dst[i][comp] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3862f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            }
3863f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3864f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3865f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3866f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT32:
3867f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT32:
3868f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT32:
3869f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3870f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3871f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowA = (const GLfloat *) srcRowA;
3872f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLfloat *rowB = (const GLfloat *) srcRowB;
3873f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLfloat *dst = (GLfloat *) dstRow;
3874f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3875f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3876f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = (rowA[j] + rowA[k] + rowB[j] + rowB[k]) * 0.25F;
3877f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3878f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3879f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3880f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_ALPHA_FLOAT16:
3881f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_LUMINANCE_FLOAT16:
3882f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul   case MESA_FORMAT_INTENSITY_FLOAT16:
3883f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      {
3884f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLuint i, j, k;
3885f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowA = (const GLhalfARB *) srcRowA;
3886f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         const GLhalfARB *rowB = (const GLhalfARB *) srcRowB;
3887f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         GLhalfARB *dst = (GLhalfARB *) dstRow;
3888f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         for (i = j = 0, k = k0; i < (GLuint) dstWidth;
3889f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul              i++, j += colStride, k += colStride) {
3890f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            GLfloat aj, ak, bj, bk;
3891f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            aj = _mesa_half_to_float(rowA[j]);
3892f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            ak = _mesa_half_to_float(rowA[k]);
3893f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bj = _mesa_half_to_float(rowB[j]);
3894f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            bk = _mesa_half_to_float(rowB[k]);
3895f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul            dst[i] = _mesa_float_to_half((aj + ak + bj + bk) * 0.25F);
3896f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul         }
3897f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      }
3898f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul      return;
3899f959f6e1dc27c71fc0ccc56e09b29101b3bf3b97Brian Paul
39003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   default:
39013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      _mesa_problem(NULL, "bad format in do_row()");
39023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
39033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
39043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul/*
39079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * These functions generate a 1/2-size mipmap image from a source image.
39089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * Texture borders are handled by copying or averaging the source image's
39099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul * border texels, depending on the scale-down factor.
39109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul */
39113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
39133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_1d_mipmap(const struct gl_texture_format *format, GLint border,
39143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, const GLubyte *srcPtr,
39153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLubyte *dstPtr)
39163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
39173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
39183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *src;
39193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
39203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* skip the border pixel, if any */
39223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   src = srcPtr + border * bpt;
39233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * bpt;
39243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* we just duplicate the input row, kind of hack, saves code */
39269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   do_row(format, srcWidth - 2 * border, src, src,
39279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          dstWidth - 2 * border, dst);
39283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border) {
39303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy left-most pixel from source */
39313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
39323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* copy right-most pixel from source */
39333893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
39343893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt,
39353893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             bpt);
39363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
39373893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
39383893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39393893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
3940b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul/**
3941b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul * XXX need to use the tex image's row stride!
3942b0b6d1abe5c7e629baebd4bf3d3ee3b17ba6ff08Brian Paul */
39433893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
39443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_2d_mipmap(const struct gl_texture_format *format, GLint border,
39453893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, const GLubyte *srcPtr,
39463893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLubyte *dstPtr)
39473893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
39483893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint bpt = format->TexelBytes;
39499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
39509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
39519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
39523893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint srcRowStride = bpt * srcWidth;
39533893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLint dstRowStride = bpt * dstWidth;
39543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   const GLubyte *srcA, *srcB;
39553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLubyte *dst;
3956462183fe4cb6df6d90632d9e2cee881c8d26b1cbAlan Hourihane   GLint row;
39573893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39583893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   /* Compute src and dst pointers, skipping any border */
39593893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   srcA = srcPtr + border * ((srcWidth + 1) * bpt);
39603893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (srcHeight > 1)
39613893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA + srcRowStride;
39623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   else
39633893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB = srcA;
39643893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   dst = dstPtr + border * ((dstWidth + 1) * bpt);
39653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (row = 0; row < dstHeightNB; row++) {
39679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB, srcA, srcB,
39689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dst);
39693893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcA += 2 * srcRowStride;
39703893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcB += 2 * srcRowStride;
39713893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      dst += dstRowStride;
39723893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
39733893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
39748bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   /* This is ugly but probably won't be used much */
39753893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   if (border > 0) {
39763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* fill in dest border */
39773893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-left border pixel */
39783893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr, srcPtr, bpt);
39793893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower-right border pixel */
39803893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth - 1) * bpt,
39813893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth - 1) * bpt, bpt);
39823893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-left border pixel */
39833893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + dstWidth * (dstHeight - 1) * bpt,
39843893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + srcWidth * (srcHeight - 1) * bpt, bpt);
39853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper-right border pixel */
39863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      MEMCPY(dstPtr + (dstWidth * dstHeight - 1) * bpt,
39873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * srcHeight - 1) * bpt, bpt);
39883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* lower border */
39899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
39909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
39919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             srcPtr + bpt,
39929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB, dstPtr + bpt);
39933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* upper border */
39949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      do_row(format, srcWidthNB,
39953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
39963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             srcPtr + (srcWidth * (srcHeight - 1) + 1) * bpt,
39979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul             dstWidthNB,
39983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul             dstPtr + (dstWidth * (dstHeight - 1) + 1) * bpt);
39993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* left and right borders */
40009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcHeight == dstHeight) {
40019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* copy border pixel from src to dst */
40029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 1; row < srcHeight; row++) {
40039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + dstWidth * row * bpt,
40049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + srcWidth * row * bpt, bpt);
40059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dstPtr + (dstWidth * row + dstWidth - 1) * bpt,
40069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * row + srcWidth - 1) * bpt, bpt);
40079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
40089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
40099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
40109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average two src pixels each dest pixel */
40119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (row = 0; row < dstHeightNB; row += 2) {
40129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
40139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1)) * bpt,
40149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2)) * bpt,
40159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1) * bpt);
40169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1,
40179228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 1) + srcWidth - 1) * bpt,
40189228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   srcPtr + (srcWidth * (row * 2 + 2) + srcWidth - 1) * bpt,
40199228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                   1, dstPtr + (dstWidth * row + 1 + dstWidth - 1) * bpt);
40209228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
40213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
40223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
40233893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
40243893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40263893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulstatic void
40273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulmake_3d_mipmap(const struct gl_texture_format *format, GLint border,
40283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint srcWidth, GLint srcHeight, GLint srcDepth,
40293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               const GLubyte *srcPtr,
40303893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLint dstWidth, GLint dstHeight, GLint dstDepth,
40313893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul               GLubyte *dstPtr)
40323893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
40339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint bpt = format->TexelBytes;
40349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcWidthNB = srcWidth - 2 * border;  /* sizes w/out border */
40359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint srcDepthNB = srcDepth - 2 * border;
40369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstWidthNB = dstWidth - 2 * border;
40379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstHeightNB = dstHeight - 2 * border;
40389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   const GLint dstDepthNB = dstDepth - 2 * border;
40399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLvoid *tmpRowA, *tmpRowB;
40403893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   GLint img, row;
40419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcImage, bytesPerDstImage;
40429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint bytesPerSrcRow, bytesPerDstRow;
40439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   GLint srcImageOffset, srcRowOffset;
40443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40455c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul   (void) srcDepthNB; /* silence warnings */
40465c749d9e3c7824c0ba5b22e37d0ea5cbd54d6d2dBrian Paul
40479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Need two temporary row buffers */
40482dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowA = _mesa_malloc(srcWidth * bpt);
40499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowA)
40509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      return;
40512dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   tmpRowB = _mesa_malloc(srcWidth * bpt);
40529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (!tmpRowB) {
40532dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      _mesa_free(tmpRowA);
40543893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      return;
40553893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
40563893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcImage = srcWidth * srcHeight * bpt;
40589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstImage = dstWidth * dstHeight * bpt;
40599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
40609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerSrcRow = srcWidth * bpt;
40619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   bytesPerDstRow = dstWidth * bpt;
40623893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src images to be averaged together */
40649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcImageOffset = (srcDepth == dstDepth) ? 0 : bytesPerSrcImage;
40653893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Offset between adjacent src rows to be averaged together */
40679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   srcRowOffset = (srcHeight == dstHeight) ? 0 : srcWidth * bpt;
40683893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
40709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Need to average together up to 8 src pixels for each dest pixel.
40719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    * Break that down into 3 operations:
40729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   1. take two rows from source image and average them together.
40739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   2. take two rows from next source image and average them together.
40749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    *   3. take the two averaged rows and average them for the final dst row.
40759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul    */
40763893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
40779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /*
40784e9676fb13f60ecdbc247b120031f18cd3febcb0Brian Paul   _mesa_printf("mip3d %d x %d x %d  ->  %d x %d x %d\n",
40799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul          srcWidth, srcHeight, srcDepth, dstWidth, dstHeight, dstDepth);
40809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   */
40819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
40829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   for (img = 0; img < dstDepthNB; img++) {
40839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* first source image pointer, skipping border */
40849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcA = srcPtr
40859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerSrcImage + bytesPerSrcRow + border) * bpt * border
40869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * (bytesPerSrcImage + srcImageOffset);
40879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* second source image pointer, skipping border */
40889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *imgSrcB = imgSrcA + srcImageOffset;
40899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* address of the dest image, skipping border */
40909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *imgDst = dstPtr
40919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + (bytesPerDstImage + bytesPerDstRow + border) * bpt * border
40929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         + img * bytesPerDstImage;
40939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
40949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* setup the four source row pointers and the dest row pointer */
40959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowA = imgSrcA;
40969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgARowB = imgSrcA + srcRowOffset;
40979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowA = imgSrcB;
40989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      const GLubyte *srcImgBRowB = imgSrcB + srcRowOffset;
40999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      GLubyte *dstImgRow = imgDst;
41009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      for (row = 0; row < dstHeightNB; row++) {
41029228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from first src image */
41039228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgARowA, srcImgARowB,
41049228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowA);
41059228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together two rows from second src image */
41069228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, srcImgBRowA, srcImgBRowB,
41079228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                srcWidthNB, tmpRowB);
41089228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* Average together the temp rows to make the final row */
41099228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         do_row(format, srcWidthNB, tmpRowA, tmpRowB,
41109228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                dstWidthNB, dstImgRow);
41119228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* advance to next rows */
41129228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowA += bytesPerSrcRow + srcRowOffset;
41139228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgARowB += bytesPerSrcRow + srcRowOffset;
41149228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowA += bytesPerSrcRow + srcRowOffset;
41159228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         srcImgBRowB += bytesPerSrcRow + srcRowOffset;
41169228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         dstImgRow += bytesPerDstRow;
41173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
41183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   }
41193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
41202dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowA);
41212dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul   _mesa_free(tmpRowB);
41229228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41239228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   /* Luckily we can leverage the make_2d_mipmap() function here! */
41249228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   if (border > 0) {
41259228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do front border image */
41269228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight, srcPtr,
41279228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight, dstPtr);
41289228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do back border image */
41299228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      make_2d_mipmap(format, 1, srcWidth, srcHeight,
41309228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     srcPtr + bytesPerSrcImage * (srcDepth - 1),
41319228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstWidth, dstHeight,
41329228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                     dstPtr + bytesPerDstImage * (dstDepth - 1));
41339228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* do four remaining border edges that span the image slices */
41349228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      if (srcDepth == dstDepth) {
41359228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* just copy border pixels from src to dst */
41369228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
41379228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
41389228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
41399228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41409228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
41419228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img + 1) * bytesPerSrcImage;
41429228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
41439228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
41449228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41459228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
41469228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41479228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
41489228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41499228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
41509228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
41519228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41529228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
41539228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41549228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
41559228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41569228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
41579228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
41589228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41599228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
41609228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41619228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
41629228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41639228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
41649228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            MEMCPY(dst, src, bpt);
41659228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
41669228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
41679228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      else {
41689228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         /* average border pixels from adjacent src image pairs */
41699228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         ASSERT(srcDepthNB == 2 * dstDepthNB);
41709228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         for (img = 0; img < dstDepthNB; img++) {
41719228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            const GLubyte *src;
41729228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            GLubyte *dst;
41739228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41749228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=0] */
41759228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage;
41769228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage;
41779228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
41789228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41799228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=0] */
41809228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41819228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcHeight - 1) * bytesPerSrcRow;
41829228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41839228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstHeight - 1) * bytesPerDstRow;
41849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
41859228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41869228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=0][col=dstWidth-1] */
41879228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41889228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (srcWidth - 1) * bpt;
41899228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41909228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (dstWidth - 1) * bpt;
41919228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
41929228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul
41939228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            /* do border along [img][row=dstHeight-1][col=dstWidth-1] */
41949228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            src = srcPtr + (img * 2 + 1) * bytesPerSrcImage
41959228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerSrcImage - bpt);
41969228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            dst = dstPtr + (img + 1) * bytesPerDstImage
41979228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul                         + (bytesPerDstImage - bpt);
41989228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul            do_row(format, 1, src, src + srcImageOffset, 1, dst);
41999228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul         }
42009228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      }
42019228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul   }
42023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
42033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
42043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
42055999c5b620236fb6a996cf56759aec31f01c126bBrian Paul/**
42063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * For GL_SGIX_generate_mipmap:
42073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Generate a complete set of mipmaps from texObj's base-level image.
42083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul * Stop at texObj's MaxLevel or when we get to the 1x1 texture.
42093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul */
42103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paulvoid
4211d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul_mesa_generate_mipmap(GLcontext *ctx, GLenum target,
42123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      const struct gl_texture_unit *texUnit,
42133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul                      struct gl_texture_object *texObj)
42143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul{
42152ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_image *srcImage;
42162ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   const struct gl_texture_format *convertFormat;
4217b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   const GLubyte *srcData = NULL;
4218b3f717037dcba37b4ac32c9ec17061781414a8caBrian Paul   GLubyte *dstData = NULL;
4219ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   GLint level, maxLevels;
42203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
42213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul   ASSERT(texObj);
4222c039af165d5919008c6df599795951f85dea164dBrian Paul   /* XXX choose cube map face here??? */
422318fa367ac6e035341f5eb86ecc4231124b2921e3Keith Whitwell   srcImage = texObj->Image[0][texObj->BaseLevel];
42242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   ASSERT(srcImage);
42253893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
4226ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
4227ef31f60b12abc2109568fb8d9a2aaa70ec5c71ccBrian Paul   ASSERT(maxLevels > 0);  /* bad target */
42283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
42292ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   /* Find convertFormat - the format that do_row() will process */
42302ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   if (srcImage->IsCompressed) {
42312ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* setup for compressed textures */
4232d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLuint row;
4233d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz      GLint  components, size;
42342ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      GLchan *dst;
42352ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
42362ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      assert(texObj->Target == GL_TEXTURE_2D);
42372ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
4238a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      if (srcImage->_BaseFormat == GL_RGB) {
42392ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgb;
42402ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 3;
42412ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
4242a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      else if (srcImage->_BaseFormat == GL_RGBA) {
42432ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         convertFormat = &_mesa_texformat_rgba;
42442ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         components = 4;
42452ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
42462ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      else {
4247a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         _mesa_problem(ctx, "bad srcImage->_BaseFormat in _mesa_generate_mipmaps");
42482ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
42492ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
42502ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
42512ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* allocate storage for uncompressed GL_RGB or GL_RGBA images */
4252a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul      size = _mesa_bytes_per_pixel(srcImage->_BaseFormat, CHAN_TYPE)
42532ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         * srcImage->Width * srcImage->Height * srcImage->Depth + 20;
42542ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* 20 extra bytes, just be safe when calling last FetchTexel */
42552dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      srcData = (GLubyte *) _mesa_malloc(size);
42562ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!srcData) {
42572ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
42582ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
42592ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
42602dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul      dstData = (GLubyte *) _mesa_malloc(size / 2);  /* 1/4 would probably be OK */
42612ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      if (!dstData) {
42622ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generate mipmaps");
42632dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul         _mesa_free((void *) srcData);
42642ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         return;
42652ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      }
42662ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul
42672ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* decompress base image here */
42682ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      dst = (GLchan *) srcData;
42692ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      for (row = 0; row < srcImage->Height; row++) {
4270d3975341e743b3436a69dedd864ccedc56b0db03Karl Schultz         GLuint col;
42712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         for (col = 0; col < srcImage->Width; col++) {
42724f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul            srcImage->FetchTexelc(srcImage, col, row, 0, dst);
42732ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            dst += components;
427489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
427589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
427689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul   }
42772ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   else {
42782ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      /* uncompressed */
42792ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul      convertFormat = srcImage->TexFormat;
42802ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul   }
428189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
42828bd06931018d5662b92f1cfeee2abaf352d0044cBrian Paul   for (level = texObj->BaseLevel; level < texObj->MaxLevel
4283cd1cefae9146fc14b35ee93a04bdb1b1590fba7bBrian Paul           && level < maxLevels - 1; level++) {
42849228e17bb5bf219269daeed5cbfdd912c118e926Brian Paul      /* generate image[level+1] from image[level] */
42853893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      const struct gl_texture_image *srcImage;
42863893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      struct gl_texture_image *dstImage;
42873893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint srcWidth, srcHeight, srcDepth;
42883893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint dstWidth, dstHeight, dstDepth;
42893893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      GLint border, bytesPerTexel;
42903893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
429189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* get src image parameters */
42923ac8105e9cbed4c531c38636f83065b2ef3ab002Brian Paul      srcImage = _mesa_select_tex_image(ctx, texUnit, target, level);
42933893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      ASSERT(srcImage);
42943893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcWidth = srcImage->Width;
42953893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcHeight = srcImage->Height;
42963893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      srcDepth = srcImage->Depth;
42973893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      border = srcImage->Border;
42983893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
42993893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      /* compute next (level+1) image size */
43003893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcWidth - 2 * border > 1) {
43013893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = (srcWidth - 2 * border) / 2 + 2 * border;
43023893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43033893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
43043893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstWidth = srcWidth; /* can't go smaller */
43053893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43063893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcHeight - 2 * border > 1) {
43073893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = (srcHeight - 2 * border) / 2 + 2 * border;
43083893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43093893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
43103893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstHeight = srcHeight; /* can't go smaller */
43113893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43123893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (srcDepth - 2 * border > 1) {
43133893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = (srcDepth - 2 * border) / 2 + 2 * border;
43143893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43153893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      else {
43163893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         dstDepth = srcDepth; /* can't go smaller */
43173893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43183893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
43193893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      if (dstWidth == srcWidth &&
43203893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstHeight == srcHeight &&
43213893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul          dstDepth == srcDepth) {
43223893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         /* all done */
432389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (srcImage->IsCompressed) {
43242dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free((void *) srcData);
43252dbffb30f05fcf67658c64b8101e9efaf07ca388Brian Paul            _mesa_free(dstData);
432689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
43273893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul         return;
43283893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul      }
43293893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
4330d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* get dest gl_texture_image */
4331a3f137094cd965d27e1b088499dd609b81a91906Brian Paul      dstImage = _mesa_get_tex_image(ctx, texUnit, target, level + 1);
4332d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (!dstImage) {
4333a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
4334a3f137094cd965d27e1b088499dd609b81a91906Brian Paul         return;
4335d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
43363893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul
4337d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* Free old image data */
4338d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      if (dstImage->Data)
43394cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         ctx->Driver.FreeTexImageData(ctx, dstImage);
4340d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
4341d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /* initialize new image */
4342e1cb2fb571ee47b59020db7627e554b7d227e454Brian Paul      _mesa_init_teximage_fields(ctx, target, dstImage, dstWidth, dstHeight,
4343a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul                                 dstDepth, border, srcImage->InternalFormat);
4344d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->DriverData = NULL;
4345d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      dstImage->TexFormat = srcImage->TexFormat;
43464f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelc = srcImage->FetchTexelc;
43474f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      dstImage->FetchTexelf = srcImage->FetchTexelf;
43485999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      dstImage->IsCompressed = srcImage->IsCompressed;
43495999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      if (dstImage->IsCompressed) {
43505999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         dstImage->CompressedSize
43515999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = ctx->Driver.CompressedTextureSize(ctx, dstImage->Width,
43525999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Height,
43535999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->Depth,
43545999c5b620236fb6a996cf56759aec31f01c126bBrian Paul                                              dstImage->TexFormat->MesaFormat);
43555999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         ASSERT(dstImage->CompressedSize > 0);
43565999c5b620236fb6a996cf56759aec31f01c126bBrian Paul      }
43575999c5b620236fb6a996cf56759aec31f01c126bBrian Paul
4358d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      ASSERT(dstImage->TexFormat);
43594f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelc);
43604f295cee73bae1f687efe2dc062522b40d90b1e4Brian Paul      ASSERT(dstImage->FetchTexelf);
4361d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
436289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      /* Alloc new teximage data buffer.
436389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       * Setup src and dest data pointers.
436489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul       */
436589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
43664cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstImage->CompressedSize);
436789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
436889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
436989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
437089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
43712ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* srcData and dstData are already set */
437289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(srcData);
437389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstData);
437489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
437589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      else {
43765999c5b620236fb6a996cf56759aec31f01c126bBrian Paul         bytesPerTexel = dstImage->TexFormat->TexelBytes;
437789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         ASSERT(dstWidth * dstHeight * dstDepth * bytesPerTexel > 0);
43784cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul         dstImage->Data = _mesa_alloc_texmemory(dstWidth * dstHeight
43794cf6718725c7cf3bfb728118a8b14f8cf206c701Brian Paul                                                * dstDepth * bytesPerTexel);
438089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         if (!dstImage->Data) {
438189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_error(ctx, GL_OUT_OF_MEMORY, "generating mipmaps");
438289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
438389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         }
438489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = (const GLubyte *) srcImage->Data;
438589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = (GLubyte *) dstImage->Data;
4386d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
4387d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul
4388d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      /*
4389d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       * We use simple 2x2 averaging to compute the next mipmap level.
4390d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul       */
4391d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      switch (target) {
439289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_1D:
43932ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_1d_mipmap(convertFormat, border,
439489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcData,
439589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstData);
439689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
439789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_2D:
439889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
439989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
440089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
440189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
440289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
440389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
44042ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_2d_mipmap(convertFormat, border,
440589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcData,
440689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstData);
440789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
440889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_3D:
44092ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul            make_3d_mipmap(convertFormat, border,
441089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           srcWidth, srcHeight, srcDepth, srcData,
441189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul                           dstWidth, dstHeight, dstDepth, dstData);
441289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
441389fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         case GL_TEXTURE_RECTANGLE_NV:
441489fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            /* no mipmaps, do nothing */
441589fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            break;
441689fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         default:
441789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            _mesa_problem(ctx, "bad dimensions in _mesa_generate_mipmaps");
441889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul            return;
4419d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul      }
442089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
442189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      if (dstImage->IsCompressed) {
442289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         GLubyte *temp;
44232ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         /* compress image from dstData into dstImage->Data */
44242ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         const GLenum srcFormat = convertFormat->BaseFormat;
4425a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         GLint dstRowStride
44265999c5b620236fb6a996cf56759aec31f01c126bBrian Paul            = _mesa_compressed_row_stride(dstImage->TexFormat->MesaFormat, dstWidth);
44272ce0654ebabc7fc6a2881f51e496e4e1f7533087Brian Paul         ASSERT(srcFormat == GL_RGB || srcFormat == GL_RGBA);
4428a9fc8ba756dd25a07dc19058fe60f65bda82a055Brian Paul         dstImage->TexFormat->StoreImage(ctx, 2, dstImage->_BaseFormat,
44298f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->TexFormat,
44308f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstImage->Data,
44318f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         0, 0, 0, /* dstX/Y/Zoffset */
44328f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstRowStride, 0, /* strides */
44338f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstWidth, dstHeight, 1, /* size */
44348f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         srcFormat, CHAN_TYPE,
44358f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         dstData, /* src data, actually */
44368f04c12e0ad876baa7eb9ed379e2b00150b376e0Brian Paul                                         &ctx->DefaultPacking);
443789fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         /* swap src and dest pointers */
443889fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         temp = (GLubyte *) srcData;
443989fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         srcData = dstData;
444089fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul         dstData = temp;
444189fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul      }
444289fb06fcc11cbe3f23521312155d6c55d869f526Brian Paul
4443d5bbbd41c431ad93c0867d5b0b234426d8570499Brian Paul   } /* loop over mipmap levels */
44443893e638e6521b9c070e01c0b31d22754ff97a88Brian Paul}
444580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
444680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
444780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul/**
444880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Helper function for drivers which need to rescale texture images to
444980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * certain aspect ratios.
445080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * Nearest filtering only (for broken hardware that can't support
445180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * all aspect ratios).  This can be made a lot faster, but I don't
445280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul * really care enough...
445380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul */
44541cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borcavoid
44551cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca_mesa_rescale_teximage2d (GLuint bytesPerPixel,
44561cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint srcStrideInPixels,
44571cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLuint dstRowStride,
44581cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint srcWidth, GLint srcHeight,
44591cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  GLint dstWidth, GLint dstHeight,
44601cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca			  const GLvoid *srcImage, GLvoid *dstImage)
446180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul{
446280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   GLint row, col;
446380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
446480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define INNER_LOOP( TYPE, HOP, WOP )					\
446580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   for ( row = 0 ; row < dstHeight ; row++ ) {				\
446680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      GLint srcRow = row HOP hScale;					\
446780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      for ( col = 0 ; col < dstWidth ; col++ ) {			\
446880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 GLint srcCol = col WOP wScale;					\
44691cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca	 dst[col] = src[srcRow * srcStrideInPixels + srcCol];		\
447080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
447180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      dst = (TYPE *) ((GLubyte *) dst + dstRowStride);			\
447280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
447380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
447480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul#define RESCALE_IMAGE( TYPE )						\
447580fc5ea53e0f1dac9df529965687c159acae057fBrian Pauldo {									\
447680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   const TYPE *src = (const TYPE *)srcImage;				\
447780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   TYPE *dst = (TYPE *)dstImage;					\
447880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul									\
44791cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca   if ( srcHeight < dstHeight ) {					\
448080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = dstHeight / srcHeight;			\
44811cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
448280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
448380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, / );					\
448480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
448580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
448680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
448780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, /, * );					\
448880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
448980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
449080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   else {								\
449180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      const GLint hScale = srcHeight / dstHeight;			\
44921cfe1e8925f8e1b89df5330895255a038be7f122Daniel Borca      if ( srcWidth < dstWidth ) {					\
449380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = dstWidth / srcWidth;			\
449480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, / );					\
449580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
449680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      else {								\
449780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 const GLint wScale = srcWidth / dstWidth;			\
449880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul	 INNER_LOOP( TYPE, *, * );					\
449980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      }									\
450080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }									\
450180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul} while (0)
450280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
450380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   switch ( bytesPerPixel ) {
450480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 4:
450580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLuint );
450680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
450780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
450880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 2:
450980fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLushort );
451080fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
451180fc5ea53e0f1dac9df529965687c159acae057fBrian Paul
451280fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   case 1:
451380fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      RESCALE_IMAGE( GLubyte );
451480fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      break;
451580fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   default:
451680fc5ea53e0f1dac9df529965687c159acae057fBrian Paul      _mesa_problem(NULL,"unexpected bytes/pixel in _mesa_rescale_teximage2d");
451780fc5ea53e0f1dac9df529965687c159acae057fBrian Paul   }
451880fc5ea53e0f1dac9df529965687c159acae057fBrian Paul}
451933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
452033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
452133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca/**
452233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * Upscale an image by replication, not (typical) stretching.
452333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * We use this when the image width or height is less than a
452433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca * certain size (4, 8) and we need to upscale an image.
452533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca */
452633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borcavoid
452733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca_mesa_upscale_teximage2d (GLsizei inWidth, GLsizei inHeight,
452833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLsizei outWidth, GLsizei outHeight,
452933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLint comps, const GLchan *src, GLint srcRowStride,
453033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca                          GLchan *dest )
453133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca{
453233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   GLint i, j, k;
453333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
453433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outWidth >= inWidth);
453533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT(outHeight >= inHeight);
453633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#if 0
4537701987c877b5346f39b2258c45cf2b6c989fd9ccDaniel Borca   ASSERT(inWidth == 1 || inWidth == 2 || inHeight == 1 || inHeight == 2);
453833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outWidth & 3) == 0);
453933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   ASSERT((outHeight & 3) == 0);
454033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca#endif
454133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca
454233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   for (i = 0; i < outHeight; i++) {
454333ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      const GLint ii = i % inHeight;
454433ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      for (j = 0; j < outWidth; j++) {
454533ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         const GLint jj = j % inWidth;
454633ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         for (k = 0; k < comps; k++) {
454733ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca            dest[(i * outWidth + j) * comps + k]
454833ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca               = src[ii * srcRowStride + jj * comps + k];
454933ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca         }
455033ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca      }
455133ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca   }
455233ffbd1c58dc8582f67d946f9eb26127e9851a10Daniel Borca}
455368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
455468d293b03535ca50daf70650b32db780f1718a3bBrian Paul
45550a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#if FEATURE_EXT_texture_sRGB
45560a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
45570a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul/**
45580a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul * Test if given texture image is an sRGB format.
45590a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul */
45600a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulstatic GLboolean
45610a4be7036864efa6b30d78e0aac449d34b812c13Brian Paulis_srgb_teximage(const struct gl_texture_image *texImage)
45620a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul{
45630a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   switch (texImage->TexFormat->MesaFormat) {
45640a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SRGB8:
45650a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SRGBA8:
45660a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SL8:
45670a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   case MESA_FORMAT_SLA8:
45680a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul      return GL_TRUE;
45690a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   default:
45700a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul      return GL_FALSE;
45710a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul   }
45720a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul}
45730a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
45740a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
45750a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul
457668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
457768d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
457868d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetTexImage().
457968d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
458068d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
458168d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
458268d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
458368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   GLenum format, GLenum type, GLvoid *pixels,
4584ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_object *texObj,
4585ea4fe661d7f3a95d9db17e1475076f1badf8e1a6Brian Paul                   struct gl_texture_image *texImage)
458668d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
4587ad15866ef0e77478508eeb534b28f0136462b644Brian Paul   const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
458868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
458968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
4590ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      /* Packing texture image into a PBO.
4591ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * Map the (potentially) VRAM-based buffer into our process space so
4592ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * we can write into it with the code below.
4593ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * A hardware driver might use a sophisticated blit to move the
4594ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * texture data to the PBO if the PBO is in VRAM along with the texture.
4595ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       */
4596ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      GLubyte *buf = (GLubyte *)
4597ad15866ef0e77478508eeb534b28f0136462b644Brian Paul         ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
4598ad15866ef0e77478508eeb534b28f0136462b644Brian Paul                               GL_WRITE_ONLY_ARB, ctx->Pack.BufferObj);
459968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
460068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
460168d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,"glGetTexImage(PBO is mapped)");
460268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
460368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
4604ad15866ef0e77478508eeb534b28f0136462b644Brian Paul      /* <pixels> was an offset into the PBO.
4605ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       * Now make it a real, client-side pointer inside the mapped region.
4606ad15866ef0e77478508eeb534b28f0136462b644Brian Paul       */
460768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      pixels = ADD_POINTERS(buf, pixels);
460868d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
460968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!pixels) {
461068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
461168d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
461268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
461368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
461468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   {
461568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint width = texImage->Width;
461668d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint height = texImage->Height;
461768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      const GLint depth = texImage->Depth;
461868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLint img, row;
461968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      for (img = 0; img < depth; img++) {
462068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         for (row = 0; row < height; row++) {
462168d293b03535ca50daf70650b32db780f1718a3bBrian Paul            /* compute destination address in client memory */
462268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            GLvoid *dest = _mesa_image_address( dimensions, &ctx->Pack, pixels,
462368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                width, height, format, type,
462468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                                img, row, 0);
462568d293b03535ca50daf70650b32db780f1718a3bBrian Paul            assert(dest);
462668d293b03535ca50daf70650b32db780f1718a3bBrian Paul
462768d293b03535ca50daf70650b32db780f1718a3bBrian Paul            if (format == GL_COLOR_INDEX) {
462868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLuint indexRow[MAX_WIDTH];
462968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
463068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* Can't use FetchTexel here because that returns RGBA */
463168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if (texImage->TexFormat->IndexBits == 8) {
463268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLubyte *src = (const GLubyte *) texImage->Data;
4633184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
463468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4635184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
463668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
463768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
463868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (texImage->TexFormat->IndexBits == 16) {
463968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  const GLushort *src = (const GLushort *) texImage->Data;
4640184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  src += width * (img * texImage->Height + row);
464168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  for (col = 0; col < width; col++) {
4642184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                     indexRow[col] = src[col];
464368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  }
464468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
464568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else {
464668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_problem(ctx,
464768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                "Color index problem in _mesa_GetTexImage");
464868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
464968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_index_span(ctx, width, type, dest,
465068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     indexRow, &ctx->Pack,
465168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     0 /* no image transfer */);
465268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
465368d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_DEPTH_COMPONENT) {
465468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat depthRow[MAX_WIDTH];
465568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
465668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
465768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img,
465868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                           depthRow + col);
465968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
466068d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_depth_span(ctx, width, dest, type,
466168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                     depthRow, &ctx->Pack);
466268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
4663184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            else if (format == GL_DEPTH_STENCIL_EXT) {
4664184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               /* XXX Note: we're bypassing texImage->FetchTexel()! */
4665184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               const GLuint *src = (const GLuint *) texImage->Data;
4666184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               src += width * row + width * height * img;
4667184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               _mesa_memcpy(dest, src, width * sizeof(GLuint));
4668184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               if (ctx->Pack.SwapBytes) {
4669184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul                  _mesa_swap4((GLuint *) dest, width);
4670184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul               }
4671184a9707227ab024d65d352fe7c09b3e287348e9Brian Paul            }
467268d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else if (format == GL_YCBCR_MESA) {
467368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* No pixel transfer */
467468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               const GLint rowstride = texImage->RowStride;
467568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               MEMCPY(dest,
467668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      (const GLushort *) texImage->Data + row * rowstride,
467768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                      width * sizeof(GLushort));
467868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* check for byte swapping */
467968d293b03535ca50daf70650b32db780f1718a3bBrian Paul               if ((texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR
468068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_REV_MESA) ||
468168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                   (texImage->TexFormat->MesaFormat == MESA_FORMAT_YCBCR_REV
468268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                    && type == GL_UNSIGNED_SHORT_8_8_MESA)) {
468368d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  if (!ctx->Pack.SwapBytes)
468468d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     _mesa_swap2((GLushort *) dest, width);
468568d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
468668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               else if (ctx->Pack.SwapBytes) {
468768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  _mesa_swap2((GLushort *) dest, width);
468868d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
468968d293b03535ca50daf70650b32db780f1718a3bBrian Paul            }
46900a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#if FEATURE_EXT_texture_sRGB
46910a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul            else if (is_srgb_teximage(texImage)) {
46920a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               /* no pixel transfer and no non-linear to linear conversion */
46930a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               const GLint comps = texImage->TexFormat->TexelBytes;
46940a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               const GLint rowstride = comps * texImage->RowStride;
46950a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul               MEMCPY(dest,
46960a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul                      (const GLubyte *) texImage->Data + row * rowstride,
46970a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul                      comps * width * sizeof(GLubyte));
46980a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul            }
46990a4be7036864efa6b30d78e0aac449d34b812c13Brian Paul#endif /* FEATURE_EXT_texture_sRGB */
470068d293b03535ca50daf70650b32db780f1718a3bBrian Paul            else {
470168d293b03535ca50daf70650b32db780f1718a3bBrian Paul               /* general case:  convert row to RGBA format */
470268d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLfloat rgba[MAX_WIDTH][4];
470368d293b03535ca50daf70650b32db780f1718a3bBrian Paul               GLint col;
470468d293b03535ca50daf70650b32db780f1718a3bBrian Paul               for (col = 0; col < width; col++) {
470568d293b03535ca50daf70650b32db780f1718a3bBrian Paul                  (*texImage->FetchTexelf)(texImage, col, row, img, rgba[col]);
470668d293b03535ca50daf70650b32db780f1718a3bBrian Paul               }
470768d293b03535ca50daf70650b32db780f1718a3bBrian Paul               _mesa_pack_rgba_span_float(ctx, width,
470868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          (const GLfloat (*)[4]) rgba,
470968d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          format, type, dest, &ctx->Pack,
471068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                          0 /* no image transfer */);
471168d293b03535ca50daf70650b32db780f1718a3bBrian Paul            } /* format */
471268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         } /* row */
471368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      } /* img */
471468d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
471568d293b03535ca50daf70650b32db780f1718a3bBrian Paul
471668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
471768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
471868d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
471968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
472068d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
472168d293b03535ca50daf70650b32db780f1718a3bBrian Paul
472268d293b03535ca50daf70650b32db780f1718a3bBrian Paul
472368d293b03535ca50daf70650b32db780f1718a3bBrian Paul
472468d293b03535ca50daf70650b32db780f1718a3bBrian Paul/**
472568d293b03535ca50daf70650b32db780f1718a3bBrian Paul * This is the software fallback for Driver.GetCompressedTexImage().
472668d293b03535ca50daf70650b32db780f1718a3bBrian Paul * All error checking will have been done before this routine is called.
472768d293b03535ca50daf70650b32db780f1718a3bBrian Paul */
472868d293b03535ca50daf70650b32db780f1718a3bBrian Paulvoid
472968d293b03535ca50daf70650b32db780f1718a3bBrian Paul_mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
473068d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              GLvoid *img,
473168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_object *texObj,
473268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              const struct gl_texture_image *texImage)
473368d293b03535ca50daf70650b32db780f1718a3bBrian Paul{
4734a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   GLuint size;
4735a5467697336f201abee19cba1521be80e5c87d3bBrian Paul
473668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
473768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* pack texture image into a PBO */
473868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      GLubyte *buf;
473968d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if ((const GLubyte *) img + texImage->CompressedSize >
474068d293b03535ca50daf70650b32db780f1718a3bBrian Paul          (const GLubyte *) ctx->Pack.BufferObj->Size) {
474168d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
474268d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(invalid PBO access)");
474368d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
474468d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
474568d293b03535ca50daf70650b32db780f1718a3bBrian Paul      buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
474668d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              GL_WRITE_ONLY_ARB,
474768d293b03535ca50daf70650b32db780f1718a3bBrian Paul                                              ctx->Pack.BufferObj);
474868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      if (!buf) {
474968d293b03535ca50daf70650b32db780f1718a3bBrian Paul         /* buffer is already mapped - that's an error */
475068d293b03535ca50daf70650b32db780f1718a3bBrian Paul         _mesa_error(ctx, GL_INVALID_OPERATION,
475168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                     "glGetCompressedTexImage(PBO is mapped)");
475268d293b03535ca50daf70650b32db780f1718a3bBrian Paul         return;
475368d293b03535ca50daf70650b32db780f1718a3bBrian Paul      }
475468d293b03535ca50daf70650b32db780f1718a3bBrian Paul      img = ADD_POINTERS(buf, img);
475568d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
475668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   else if (!img) {
475768d293b03535ca50daf70650b32db780f1718a3bBrian Paul      /* not an error */
475868d293b03535ca50daf70650b32db780f1718a3bBrian Paul      return;
475968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
476068d293b03535ca50daf70650b32db780f1718a3bBrian Paul
4761a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   /* don't use texImage->CompressedSize since that may be padded out */
4762a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   size = _mesa_compressed_texture_size(ctx, texImage->Width, texImage->Height,
4763a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                        texImage->Depth,
4764a5467697336f201abee19cba1521be80e5c87d3bBrian Paul                                        texImage->TexFormat->MesaFormat);
4765a5467697336f201abee19cba1521be80e5c87d3bBrian Paul
476668d293b03535ca50daf70650b32db780f1718a3bBrian Paul   /* just memcpy, no pixelstore or pixel transfer */
4767a5467697336f201abee19cba1521be80e5c87d3bBrian Paul   _mesa_memcpy(img, texImage->Data, size);
476868d293b03535ca50daf70650b32db780f1718a3bBrian Paul
476968d293b03535ca50daf70650b32db780f1718a3bBrian Paul   if (ctx->Pack.BufferObj->Name) {
477068d293b03535ca50daf70650b32db780f1718a3bBrian Paul      ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
477168d293b03535ca50daf70650b32db780f1718a3bBrian Paul                              ctx->Pack.BufferObj);
477268d293b03535ca50daf70650b32db780f1718a3bBrian Paul   }
477368d293b03535ca50daf70650b32db780f1718a3bBrian Paul}
4774