OSDN Git Service

mesa: Add decoding functions for GL_COMPRESSED_RGB8_ETC2
[android-x86/external-mesa.git] / src / mesa / main / texstore.c
1 /*
2  * Mesa 3-D graphics library
3  * Version:  7.5
4  *
5  * Copyright (C) 1999-2008  Brian Paul   All Rights Reserved.
6  * Copyright (c) 2008-2009  VMware, Inc.
7  *
8  * Permission is hereby granted, free of charge, to any person obtaining a
9  * copy of this software and associated documentation files (the "Software"),
10  * to deal in the Software without restriction, including without limitation
11  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12  * and/or sell copies of the Software, and to permit persons to whom the
13  * Software is furnished to do so, subject to the following conditions:
14  *
15  * The above copyright notice and this permission notice shall be included
16  * in all copies or substantial portions of the Software.
17  *
18  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24  */
25
26 /*
27  * Authors:
28  *   Brian Paul
29  */
30
31 /**
32  * The GL texture image functions in teximage.c basically just do
33  * error checking and data structure allocation.  They in turn call
34  * device driver functions which actually copy/convert/store the user's
35  * texture image data.
36  *
37  * However, most device drivers will be able to use the fallback functions
38  * in this file.  That is, most drivers will have the following bit of
39  * code:
40  *   ctx->Driver.TexImage = _mesa_store_teximage;
41  *   ctx->Driver.TexSubImage = _mesa_store_texsubimage;
42  *   etc...
43  *
44  * Texture image processing is actually kind of complicated.  We have to do:
45  *    Format/type conversions
46  *    pixel unpacking
47  *    pixel transfer (scale, bais, lookup, etc)
48  *
49  * These functions can handle most everything, including processing full
50  * images and sub-images.
51  */
52
53
54 #include "glheader.h"
55 #include "bufferobj.h"
56 #include "colormac.h"
57 #include "format_pack.h"
58 #include "image.h"
59 #include "macros.h"
60 #include "mipmap.h"
61 #include "mfeatures.h"
62 #include "mtypes.h"
63 #include "pack.h"
64 #include "pbo.h"
65 #include "imports.h"
66 #include "texcompress.h"
67 #include "texcompress_fxt1.h"
68 #include "texcompress_rgtc.h"
69 #include "texcompress_s3tc.h"
70 #include "texcompress_etc.h"
71 #include "teximage.h"
72 #include "texstore.h"
73 #include "enums.h"
74 #include "glformats.h"
75 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
76 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
77
78
79 enum {
80    ZERO = 4, 
81    ONE = 5
82 };
83
84
85 /**
86  * Texture image storage function.
87  */
88 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
89
90
91 /**
92  * Return GL_TRUE if the given image format is one that be converted
93  * to another format by swizzling.
94  */
95 static GLboolean
96 can_swizzle(GLenum logicalBaseFormat)
97 {
98    switch (logicalBaseFormat) {
99    case GL_RGBA:
100    case GL_RGB:
101    case GL_LUMINANCE_ALPHA:
102    case GL_INTENSITY:
103    case GL_ALPHA:
104    case GL_LUMINANCE:
105    case GL_RED:
106    case GL_GREEN:
107    case GL_BLUE:
108    case GL_BGR:
109    case GL_BGRA:
110    case GL_ABGR_EXT:
111    case GL_RG:
112       return GL_TRUE;
113    default:
114       return GL_FALSE;
115    }
116 }
117
118
119
120 enum {
121    IDX_LUMINANCE = 0,
122    IDX_ALPHA,
123    IDX_INTENSITY,
124    IDX_LUMINANCE_ALPHA,
125    IDX_RGB,
126    IDX_RGBA,
127    IDX_RED,
128    IDX_GREEN,
129    IDX_BLUE,
130    IDX_BGR,
131    IDX_BGRA,
132    IDX_ABGR,
133    IDX_RG,
134    MAX_IDX
135 };
136
137 #define MAP1(x)       MAP4(x, ZERO, ZERO, ZERO)
138 #define MAP2(x,y)     MAP4(x, y, ZERO, ZERO)
139 #define MAP3(x,y,z)   MAP4(x, y, z, ZERO)
140 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
141
142
143 static const struct {
144    GLubyte format_idx;
145    GLubyte to_rgba[6];
146    GLubyte from_rgba[6];
147 } mappings[MAX_IDX] = 
148 {
149    {
150       IDX_LUMINANCE,
151       MAP4(0,0,0,ONE),
152       MAP1(0)
153    },
154
155    {
156       IDX_ALPHA,
157       MAP4(ZERO, ZERO, ZERO, 0),
158       MAP1(3)
159    },
160
161    {
162       IDX_INTENSITY,
163       MAP4(0, 0, 0, 0),
164       MAP1(0),
165    },
166
167    {
168       IDX_LUMINANCE_ALPHA,
169       MAP4(0,0,0,1),
170       MAP2(0,3)
171    },
172
173    {
174       IDX_RGB,
175       MAP4(0,1,2,ONE),
176       MAP3(0,1,2)
177    },
178
179    {
180       IDX_RGBA,
181       MAP4(0,1,2,3),
182       MAP4(0,1,2,3),
183    },
184
185    {
186       IDX_RED,
187       MAP4(0, ZERO, ZERO, ONE),
188       MAP1(0),
189    },
190
191    {
192       IDX_GREEN,
193       MAP4(ZERO, 0, ZERO, ONE),
194       MAP1(1),
195    },
196
197    {
198       IDX_BLUE,
199       MAP4(ZERO, ZERO, 0, ONE),
200       MAP1(2),
201    },
202
203    {
204       IDX_BGR,
205       MAP4(2,1,0,ONE),
206       MAP3(2,1,0)
207    },
208
209    {
210       IDX_BGRA,
211       MAP4(2,1,0,3),
212       MAP4(2,1,0,3)
213    },
214
215    {
216       IDX_ABGR,
217       MAP4(3,2,1,0),
218       MAP4(3,2,1,0)
219    },
220
221    {
222       IDX_RG,
223       MAP4(0, 1, ZERO, ONE),
224       MAP2(0, 1)
225    },
226 };
227
228
229
230 /**
231  * Convert a GL image format enum to an IDX_* value (see above).
232  */
233 static int
234 get_map_idx(GLenum value)
235 {
236    switch (value) {
237    case GL_LUMINANCE: return IDX_LUMINANCE;
238    case GL_ALPHA: return IDX_ALPHA;
239    case GL_INTENSITY: return IDX_INTENSITY;
240    case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
241    case GL_RGB: return IDX_RGB;
242    case GL_RGBA: return IDX_RGBA;
243    case GL_RED: return IDX_RED;
244    case GL_GREEN: return IDX_GREEN;
245    case GL_BLUE: return IDX_BLUE;
246    case GL_BGR: return IDX_BGR;
247    case GL_BGRA: return IDX_BGRA;
248    case GL_ABGR_EXT: return IDX_ABGR;
249    case GL_RG: return IDX_RG;
250    default:
251       _mesa_problem(NULL, "Unexpected inFormat");
252       return 0;
253    }
254 }   
255
256
257 /**
258  * When promoting texture formats (see below) we need to compute the
259  * mapping of dest components back to source components.
260  * This function does that.
261  * \param inFormat  the incoming format of the texture
262  * \param outFormat  the final texture format
263  * \return map[6]  a full 6-component map
264  */
265 static void
266 compute_component_mapping(GLenum inFormat, GLenum outFormat, 
267                           GLubyte *map)
268 {
269    const int inFmt = get_map_idx(inFormat);
270    const int outFmt = get_map_idx(outFormat);
271    const GLubyte *in2rgba = mappings[inFmt].to_rgba;
272    const GLubyte *rgba2out = mappings[outFmt].from_rgba;
273    int i;
274    
275    for (i = 0; i < 4; i++)
276       map[i] = in2rgba[rgba2out[i]];
277
278    map[ZERO] = ZERO;
279    map[ONE] = ONE;   
280
281 #if 0
282    printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
283           inFormat, _mesa_lookup_enum_by_nr(inFormat),
284           outFormat, _mesa_lookup_enum_by_nr(outFormat),
285           map[0], 
286           map[1], 
287           map[2], 
288           map[3], 
289           map[4], 
290           map[5]); 
291 #endif
292 }
293
294
295 /**
296  * Make a temporary (color) texture image with GLfloat components.
297  * Apply all needed pixel unpacking and pixel transfer operations.
298  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
299  * Suppose the user specifies GL_LUMINANCE as the internal texture format
300  * but the graphics hardware doesn't support luminance textures.  So, we might
301  * use an RGB hardware format instead.
302  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
303  *
304  * \param ctx  the rendering context
305  * \param dims  image dimensions: 1, 2 or 3
306  * \param logicalBaseFormat  basic texture derived from the user's
307  *    internal texture format value
308  * \param textureBaseFormat  the actual basic format of the texture
309  * \param srcWidth  source image width
310  * \param srcHeight  source image height
311  * \param srcDepth  source image depth
312  * \param srcFormat  source image format
313  * \param srcType  source image type
314  * \param srcAddr  source image address
315  * \param srcPacking  source image pixel packing
316  * \return resulting image with format = textureBaseFormat and type = GLfloat.
317  */
318 GLfloat *
319 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
320                             GLenum logicalBaseFormat,
321                             GLenum textureBaseFormat,
322                             GLint srcWidth, GLint srcHeight, GLint srcDepth,
323                             GLenum srcFormat, GLenum srcType,
324                             const GLvoid *srcAddr,
325                             const struct gl_pixelstore_attrib *srcPacking,
326                             GLbitfield transferOps)
327 {
328    GLfloat *tempImage;
329    const GLint components = _mesa_components_in_format(logicalBaseFormat);
330    const GLint srcStride =
331       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
332    GLfloat *dst;
333    GLint img, row;
334
335    ASSERT(dims >= 1 && dims <= 3);
336
337    ASSERT(logicalBaseFormat == GL_RGBA ||
338           logicalBaseFormat == GL_RGB ||
339           logicalBaseFormat == GL_RG ||
340           logicalBaseFormat == GL_RED ||
341           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
342           logicalBaseFormat == GL_LUMINANCE ||
343           logicalBaseFormat == GL_ALPHA ||
344           logicalBaseFormat == GL_INTENSITY ||
345           logicalBaseFormat == GL_DEPTH_COMPONENT);
346
347    ASSERT(textureBaseFormat == GL_RGBA ||
348           textureBaseFormat == GL_RGB ||
349           textureBaseFormat == GL_RG ||
350           textureBaseFormat == GL_RED ||
351           textureBaseFormat == GL_LUMINANCE_ALPHA ||
352           textureBaseFormat == GL_LUMINANCE ||
353           textureBaseFormat == GL_ALPHA ||
354           textureBaseFormat == GL_INTENSITY ||
355           textureBaseFormat == GL_DEPTH_COMPONENT);
356
357    tempImage = malloc(srcWidth * srcHeight * srcDepth
358                                   * components * sizeof(GLfloat));
359    if (!tempImage)
360       return NULL;
361
362    dst = tempImage;
363    for (img = 0; img < srcDepth; img++) {
364       const GLubyte *src
365          = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
366                                                  srcWidth, srcHeight,
367                                                  srcFormat, srcType,
368                                                  img, 0, 0);
369       for (row = 0; row < srcHeight; row++) {
370          _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
371                                        dst, srcFormat, srcType, src,
372                                        srcPacking, transferOps);
373          dst += srcWidth * components;
374          src += srcStride;
375       }
376    }
377
378    if (logicalBaseFormat != textureBaseFormat) {
379       /* more work */
380       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
381       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
382       GLfloat *newImage;
383       GLint i, n;
384       GLubyte map[6];
385
386       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
387       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
388              textureBaseFormat == GL_LUMINANCE_ALPHA);
389
390       /* The actual texture format should have at least as many components
391        * as the logical texture format.
392        */
393       ASSERT(texComponents >= logComponents);
394
395       newImage = malloc(srcWidth * srcHeight * srcDepth
396                                           * texComponents * sizeof(GLfloat));
397       if (!newImage) {
398          free(tempImage);
399          return NULL;
400       }
401
402       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
403
404       n = srcWidth * srcHeight * srcDepth;
405       for (i = 0; i < n; i++) {
406          GLint k;
407          for (k = 0; k < texComponents; k++) {
408             GLint j = map[k];
409             if (j == ZERO)
410                newImage[i * texComponents + k] = 0.0F;
411             else if (j == ONE)
412                newImage[i * texComponents + k] = 1.0F;
413             else
414                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
415          }
416       }
417
418       free(tempImage);
419       tempImage = newImage;
420    }
421
422    return tempImage;
423 }
424
425
426 /**
427  * Make temporary image with uint pixel values.  Used for unsigned
428  * integer-valued textures.
429  */
430 static GLuint *
431 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
432                      GLenum logicalBaseFormat,
433                      GLenum textureBaseFormat,
434                      GLint srcWidth, GLint srcHeight, GLint srcDepth,
435                      GLenum srcFormat, GLenum srcType,
436                      const GLvoid *srcAddr,
437                      const struct gl_pixelstore_attrib *srcPacking)
438 {
439    GLuint *tempImage;
440    const GLint components = _mesa_components_in_format(logicalBaseFormat);
441    const GLint srcStride =
442       _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
443    GLuint *dst;
444    GLint img, row;
445
446    ASSERT(dims >= 1 && dims <= 3);
447
448    ASSERT(logicalBaseFormat == GL_RGBA ||
449           logicalBaseFormat == GL_RGB ||
450           logicalBaseFormat == GL_RG ||
451           logicalBaseFormat == GL_RED ||
452           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
453           logicalBaseFormat == GL_LUMINANCE ||
454           logicalBaseFormat == GL_INTENSITY ||
455           logicalBaseFormat == GL_ALPHA);
456
457    ASSERT(textureBaseFormat == GL_RGBA ||
458           textureBaseFormat == GL_RGB ||
459           textureBaseFormat == GL_RG ||
460           textureBaseFormat == GL_RED ||
461           textureBaseFormat == GL_LUMINANCE_ALPHA ||
462           textureBaseFormat == GL_LUMINANCE ||
463           textureBaseFormat == GL_INTENSITY ||
464           textureBaseFormat == GL_ALPHA);
465
466    tempImage = malloc(srcWidth * srcHeight * srcDepth
467                                  * components * sizeof(GLuint));
468    if (!tempImage)
469       return NULL;
470
471    dst = tempImage;
472    for (img = 0; img < srcDepth; img++) {
473       const GLubyte *src
474          = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
475                                                  srcWidth, srcHeight,
476                                                  srcFormat, srcType,
477                                                  img, 0, 0);
478       for (row = 0; row < srcHeight; row++) {
479          _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
480                                       dst, srcFormat, srcType, src,
481                                       srcPacking);
482          dst += srcWidth * components;
483          src += srcStride;
484       }
485    }
486
487    if (logicalBaseFormat != textureBaseFormat) {
488       /* more work */
489       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
490       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
491       GLuint *newImage;
492       GLint i, n;
493       GLubyte map[6];
494
495       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
496       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
497              textureBaseFormat == GL_LUMINANCE_ALPHA);
498
499       /* The actual texture format should have at least as many components
500        * as the logical texture format.
501        */
502       ASSERT(texComponents >= logComponents);
503
504       newImage = malloc(srcWidth * srcHeight * srcDepth
505                                    * texComponents * sizeof(GLuint));
506       if (!newImage) {
507          free(tempImage);
508          return NULL;
509       }
510
511       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
512
513       n = srcWidth * srcHeight * srcDepth;
514       for (i = 0; i < n; i++) {
515          GLint k;
516          for (k = 0; k < texComponents; k++) {
517             GLint j = map[k];
518             if (j == ZERO)
519                newImage[i * texComponents + k] = 0;
520             else if (j == ONE)
521                newImage[i * texComponents + k] = 1;
522             else
523                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
524          }
525       }
526
527       free(tempImage);
528       tempImage = newImage;
529    }
530
531    return tempImage;
532 }
533
534
535
536 /**
537  * Make a temporary (color) texture image with GLubyte components.
538  * Apply all needed pixel unpacking and pixel transfer operations.
539  * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
540  * Suppose the user specifies GL_LUMINANCE as the internal texture format
541  * but the graphics hardware doesn't support luminance textures.  So, we might
542  * use an RGB hardware format instead.
543  * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
544  *
545  * \param ctx  the rendering context
546  * \param dims  image dimensions: 1, 2 or 3
547  * \param logicalBaseFormat  basic texture derived from the user's
548  *    internal texture format value
549  * \param textureBaseFormat  the actual basic format of the texture
550  * \param srcWidth  source image width
551  * \param srcHeight  source image height
552  * \param srcDepth  source image depth
553  * \param srcFormat  source image format
554  * \param srcType  source image type
555  * \param srcAddr  source image address
556  * \param srcPacking  source image pixel packing
557  * \return resulting image with format = textureBaseFormat and type = GLubyte.
558  */
559 GLubyte *
560 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
561                             GLenum logicalBaseFormat,
562                             GLenum textureBaseFormat,
563                             GLint srcWidth, GLint srcHeight, GLint srcDepth,
564                             GLenum srcFormat, GLenum srcType,
565                             const GLvoid *srcAddr,
566                             const struct gl_pixelstore_attrib *srcPacking)
567 {
568    GLuint transferOps = ctx->_ImageTransferState;
569    const GLint components = _mesa_components_in_format(logicalBaseFormat);
570    GLint img, row;
571    GLubyte *tempImage, *dst;
572
573    ASSERT(dims >= 1 && dims <= 3);
574
575    ASSERT(logicalBaseFormat == GL_RGBA ||
576           logicalBaseFormat == GL_RGB ||
577           logicalBaseFormat == GL_RG ||
578           logicalBaseFormat == GL_RED ||
579           logicalBaseFormat == GL_LUMINANCE_ALPHA ||
580           logicalBaseFormat == GL_LUMINANCE ||
581           logicalBaseFormat == GL_ALPHA ||
582           logicalBaseFormat == GL_INTENSITY);
583
584    ASSERT(textureBaseFormat == GL_RGBA ||
585           textureBaseFormat == GL_RGB ||
586           textureBaseFormat == GL_RG ||
587           textureBaseFormat == GL_RED ||
588           textureBaseFormat == GL_LUMINANCE_ALPHA ||
589           textureBaseFormat == GL_LUMINANCE ||
590           textureBaseFormat == GL_ALPHA ||
591           textureBaseFormat == GL_INTENSITY);
592
593    /* unpack and transfer the source image */
594    tempImage = malloc(srcWidth * srcHeight * srcDepth
595                                        * components * sizeof(GLubyte));
596    if (!tempImage) {
597       return NULL;
598    }
599
600    dst = tempImage;
601    for (img = 0; img < srcDepth; img++) {
602       const GLint srcStride =
603          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
604       const GLubyte *src =
605          (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
606                                                srcWidth, srcHeight,
607                                                srcFormat, srcType,
608                                                img, 0, 0);
609       for (row = 0; row < srcHeight; row++) {
610          _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
611                                        srcFormat, srcType, src, srcPacking,
612                                        transferOps);
613          dst += srcWidth * components;
614          src += srcStride;
615       }
616    }
617
618    if (logicalBaseFormat != textureBaseFormat) {
619       /* one more conversion step */
620       GLint texComponents = _mesa_components_in_format(textureBaseFormat);
621       GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
622       GLubyte *newImage;
623       GLint i, n;
624       GLubyte map[6];
625
626       /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
627       ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
628              textureBaseFormat == GL_LUMINANCE_ALPHA);
629
630       /* The actual texture format should have at least as many components
631        * as the logical texture format.
632        */
633       ASSERT(texComponents >= logComponents);
634
635       newImage = malloc(srcWidth * srcHeight * srcDepth
636                                          * texComponents * sizeof(GLubyte));
637       if (!newImage) {
638          free(tempImage);
639          return NULL;
640       }
641
642       compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
643
644       n = srcWidth * srcHeight * srcDepth;
645       for (i = 0; i < n; i++) {
646          GLint k;
647          for (k = 0; k < texComponents; k++) {
648             GLint j = map[k];
649             if (j == ZERO)
650                newImage[i * texComponents + k] = 0;
651             else if (j == ONE)
652                newImage[i * texComponents + k] = 255;
653             else
654                newImage[i * texComponents + k] = tempImage[i * logComponents + j];
655          }
656       }
657
658       free(tempImage);
659       tempImage = newImage;
660    }
661
662    return tempImage;
663 }
664
665
666 /**
667  * Copy GLubyte pixels from <src> to <dst> with swizzling.
668  * \param dst  destination pixels
669  * \param dstComponents  number of color components in destination pixels
670  * \param src  source pixels
671  * \param srcComponents  number of color components in source pixels
672  * \param map  the swizzle mapping.  map[X] says where to find the X component
673  *             in the source image's pixels.  For example, if the source image
674  *             is GL_BGRA and X = red, map[0] yields 2.
675  * \param count  number of pixels to copy/swizzle.
676  */
677 static void
678 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src, 
679              GLuint srcComponents, const GLubyte *map, GLuint count)
680 {
681 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
682    do {                                              \
683       GLuint i;                                      \
684       for (i = 0; i < count; i++) {                  \
685          GLuint j;                                   \
686          if (srcComps == 4) {                        \
687             COPY_4UBV(tmp, src);                     \
688          }                                           \
689          else {                                      \
690             for (j = 0; j < srcComps; j++) {         \
691                tmp[j] = src[j];                      \
692             }                                        \
693          }                                           \
694          src += srcComps;                            \
695          for (j = 0; j < dstComps; j++) {            \
696             dst[j] = tmp[map[j]];                    \
697          }                                           \
698          dst += dstComps;                            \
699       }                                              \
700    } while (0)
701
702    GLubyte tmp[6];
703
704    tmp[ZERO] = 0x0;
705    tmp[ONE] = 0xff;
706
707    ASSERT(srcComponents <= 4);
708    ASSERT(dstComponents <= 4);
709
710    switch (dstComponents) {
711    case 4:
712       switch (srcComponents) {
713       case 4:
714          SWZ_CPY(dst, src, count, 4, 4);
715          break;
716       case 3:
717          SWZ_CPY(dst, src, count, 4, 3);
718          break;
719       case 2:
720          SWZ_CPY(dst, src, count, 4, 2);
721          break;
722       case 1:
723          SWZ_CPY(dst, src, count, 4, 1);
724          break;
725       default:
726          ;
727       }
728       break;
729    case 3:
730       switch (srcComponents) {
731       case 4:
732          SWZ_CPY(dst, src, count, 3, 4);
733          break;
734       case 3:
735          SWZ_CPY(dst, src, count, 3, 3);
736          break;
737       case 2:
738          SWZ_CPY(dst, src, count, 3, 2);
739          break;
740       case 1:
741          SWZ_CPY(dst, src, count, 3, 1);
742          break;
743       default:
744          ;
745       }
746       break;
747    case 2:
748       switch (srcComponents) {
749       case 4:
750          SWZ_CPY(dst, src, count, 2, 4);
751          break;
752       case 3:
753          SWZ_CPY(dst, src, count, 2, 3);
754          break;
755       case 2:
756          SWZ_CPY(dst, src, count, 2, 2);
757          break;
758       case 1:
759          SWZ_CPY(dst, src, count, 2, 1);
760          break;
761       default:
762          ;
763       }
764       break;
765    case 1:
766       switch (srcComponents) {
767       case 4:
768          SWZ_CPY(dst, src, count, 1, 4);
769          break;
770       case 3:
771          SWZ_CPY(dst, src, count, 1, 3);
772          break;
773       case 2:
774          SWZ_CPY(dst, src, count, 1, 2);
775          break;
776       case 1:
777          SWZ_CPY(dst, src, count, 1, 1);
778          break;
779       default:
780          ;
781       }
782       break;
783    default:
784       ;
785    }
786 #undef SWZ_CPY
787 }
788
789
790
791 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
792 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
793
794
795 /**
796  * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
797  * mapping array depending on endianness.
798  */
799 static const GLubyte *
800 type_mapping( GLenum srcType )
801 {
802    switch (srcType) {
803    case GL_BYTE:
804    case GL_UNSIGNED_BYTE:
805       return map_identity;
806    case GL_UNSIGNED_INT_8_8_8_8:
807       return _mesa_little_endian() ? map_3210 : map_identity;
808    case GL_UNSIGNED_INT_8_8_8_8_REV:
809       return _mesa_little_endian() ? map_identity : map_3210;
810    default:
811       return NULL;
812    }
813 }
814
815
816 /**
817  * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
818  * mapping array depending on pixelstore byte swapping state.
819  */
820 static const GLubyte *
821 byteswap_mapping( GLboolean swapBytes,
822                   GLenum srcType )
823 {
824    if (!swapBytes) 
825       return map_identity;
826
827    switch (srcType) {
828    case GL_BYTE:
829    case GL_UNSIGNED_BYTE:
830       return map_identity;
831    case GL_UNSIGNED_INT_8_8_8_8:
832    case GL_UNSIGNED_INT_8_8_8_8_REV:
833       return map_3210;
834    default:
835       return NULL;
836    }
837 }
838
839
840
841 /**
842  * Transfer a GLubyte texture image with component swizzling.
843  */
844 static void
845 _mesa_swizzle_ubyte_image(struct gl_context *ctx, 
846                           GLuint dimensions,
847                           GLenum srcFormat,
848                           GLenum srcType,
849
850                           GLenum baseInternalFormat,
851
852                           const GLubyte *rgba2dst,
853                           GLuint dstComponents,
854
855                           GLint dstRowStride,
856                           GLubyte **dstSlices,
857
858                           GLint srcWidth, GLint srcHeight, GLint srcDepth,
859                           const GLvoid *srcAddr,
860                           const struct gl_pixelstore_attrib *srcPacking )
861 {
862    GLint srcComponents = _mesa_components_in_format(srcFormat);
863    const GLubyte *srctype2ubyte, *swap;
864    GLubyte map[4], src2base[6], base2rgba[6];
865    GLint i;
866    const GLint srcRowStride =
867       _mesa_image_row_stride(srcPacking, srcWidth,
868                              srcFormat, GL_UNSIGNED_BYTE);
869    const GLint srcImageStride
870       = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
871                                  GL_UNSIGNED_BYTE);
872    const GLubyte *srcImage
873       = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
874                                               srcWidth, srcHeight, srcFormat,
875                                               GL_UNSIGNED_BYTE, 0, 0, 0);
876
877    (void) ctx;
878
879    /* Translate from src->baseInternal->GL_RGBA->dst.  This will
880     * correctly deal with RGBA->RGB->RGBA conversions where the final
881     * A value must be 0xff regardless of the incoming alpha values.
882     */
883    compute_component_mapping(srcFormat, baseInternalFormat, src2base);
884    compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
885    swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
886    srctype2ubyte = type_mapping(srcType);
887
888
889    for (i = 0; i < 4; i++)
890       map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
891
892 /*    printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]);  */
893
894    if (srcComponents == dstComponents &&
895        srcRowStride == dstRowStride &&
896        srcRowStride == srcWidth * srcComponents &&
897        dimensions < 3) {
898       /* 1 and 2D images only */
899       GLubyte *dstImage = dstSlices[0];
900       swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map, 
901                    srcWidth * srcHeight);
902    }
903    else {
904       GLint img, row;
905       for (img = 0; img < srcDepth; img++) {
906          const GLubyte *srcRow = srcImage;
907          GLubyte *dstRow = dstSlices[img];
908          for (row = 0; row < srcHeight; row++) {
909             swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
910             dstRow += dstRowStride;
911             srcRow += srcRowStride;
912          }
913          srcImage += srcImageStride;
914       }
915    }
916 }
917
918
919 /**
920  * Teximage storage routine for when a simple memcpy will do.
921  * No pixel transfer operations or special texel encodings allowed.
922  * 1D, 2D and 3D images supported.
923  */
924 static void
925 memcpy_texture(struct gl_context *ctx,
926                GLuint dimensions,
927                gl_format dstFormat,
928                GLint dstRowStride,
929                GLubyte **dstSlices,
930                GLint srcWidth, GLint srcHeight, GLint srcDepth,
931                GLenum srcFormat, GLenum srcType,
932                const GLvoid *srcAddr,
933                const struct gl_pixelstore_attrib *srcPacking)
934 {
935    const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
936                                                      srcFormat, srcType);
937    const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
938                                       srcWidth, srcHeight, srcFormat, srcType);
939    const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
940         srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
941    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
942    const GLint bytesPerRow = srcWidth * texelBytes;
943
944    if (dstRowStride == srcRowStride &&
945        dstRowStride == bytesPerRow) {
946       /* memcpy image by image */
947       GLint img;
948       for (img = 0; img < srcDepth; img++) {
949          GLubyte *dstImage = dstSlices[img];
950          memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
951          srcImage += srcImageStride;
952       }
953    }
954    else {
955       /* memcpy row by row */
956       GLint img, row;
957       for (img = 0; img < srcDepth; img++) {
958          const GLubyte *srcRow = srcImage;
959          GLubyte *dstRow = dstSlices[img];
960          for (row = 0; row < srcHeight; row++) {
961             memcpy(dstRow, srcRow, bytesPerRow);
962             dstRow += dstRowStride;
963             srcRow += srcRowStride;
964          }
965          srcImage += srcImageStride;
966       }
967    }
968 }
969
970
971 /**
972  * General-case function for storing a color texture images with
973  * components that can be represented with ubytes.  Example destination
974  * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
975  */
976 static GLboolean
977 store_ubyte_texture(TEXSTORE_PARAMS)
978 {
979    const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
980    GLubyte *tempImage, *src;
981    GLint img;
982
983    tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
984                                            baseInternalFormat,
985                                            GL_RGBA,
986                                            srcWidth, srcHeight, srcDepth,
987                                            srcFormat, srcType, srcAddr,
988                                            srcPacking);
989    if (!tempImage)
990       return GL_FALSE;
991
992    src = tempImage;
993    for (img = 0; img < srcDepth; img++) {
994       _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
995                                  src, srcRowStride,
996                                  dstSlices[img], dstRowStride);
997       src += srcHeight * srcRowStride;
998    }
999    free(tempImage);
1000
1001    return GL_TRUE;
1002 }
1003
1004
1005
1006
1007 /**
1008  * Store a 32-bit integer or float depth component texture image.
1009  */
1010 static GLboolean
1011 _mesa_texstore_z32(TEXSTORE_PARAMS)
1012 {
1013    const GLuint depthScale = 0xffffffff;
1014    GLenum dstType;
1015    (void) dims;
1016    ASSERT(dstFormat == MESA_FORMAT_Z32 ||
1017           dstFormat == MESA_FORMAT_Z32_FLOAT);
1018    ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
1019
1020    if (dstFormat == MESA_FORMAT_Z32)
1021       dstType = GL_UNSIGNED_INT;
1022    else
1023       dstType = GL_FLOAT;
1024
1025    if (ctx->Pixel.DepthScale == 1.0f &&
1026        ctx->Pixel.DepthBias == 0.0f &&
1027        !srcPacking->SwapBytes &&
1028        baseInternalFormat == GL_DEPTH_COMPONENT &&
1029        srcFormat == GL_DEPTH_COMPONENT &&
1030        srcType == dstType) {
1031       /* simple memcpy path */
1032       memcpy_texture(ctx, dims,
1033                      dstFormat,
1034                      dstRowStride, dstSlices,
1035                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1036                      srcAddr, srcPacking);
1037    }
1038    else {
1039       /* general path */
1040       GLint img, row;
1041       for (img = 0; img < srcDepth; img++) {
1042          GLubyte *dstRow = dstSlices[img];
1043          for (row = 0; row < srcHeight; row++) {
1044             const GLvoid *src = _mesa_image_address(dims, srcPacking,
1045                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1046             _mesa_unpack_depth_span(ctx, srcWidth,
1047                                     dstType, dstRow,
1048                                     depthScale, srcType, src, srcPacking);
1049             dstRow += dstRowStride;
1050          }
1051       }
1052    }
1053    return GL_TRUE;
1054 }
1055
1056
1057 /**
1058  * Store a 24-bit integer depth component texture image.
1059  */
1060 static GLboolean
1061 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1062 {
1063    const GLuint depthScale = 0xffffff;
1064
1065    (void) dims;
1066    ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
1067
1068    {
1069       /* general path */
1070       GLint img, row;
1071       for (img = 0; img < srcDepth; img++) {
1072          GLubyte *dstRow = dstSlices[img];
1073          for (row = 0; row < srcHeight; row++) {
1074             const GLvoid *src = _mesa_image_address(dims, srcPacking,
1075                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1076             _mesa_unpack_depth_span(ctx, srcWidth,
1077                                     GL_UNSIGNED_INT, (GLuint *) dstRow,
1078                                     depthScale, srcType, src, srcPacking);
1079             dstRow += dstRowStride;
1080          }
1081       }
1082    }
1083    return GL_TRUE;
1084 }
1085
1086
1087 /**
1088  * Store a 24-bit integer depth component texture image.
1089  */
1090 static GLboolean
1091 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
1092 {
1093    const GLuint depthScale = 0xffffff;
1094
1095    (void) dims;
1096    ASSERT(dstFormat == MESA_FORMAT_Z24_X8);
1097
1098    {
1099       /* general path */
1100       GLint img, row;
1101       for (img = 0; img < srcDepth; img++) {
1102          GLubyte *dstRow = dstSlices[img];
1103          for (row = 0; row < srcHeight; row++) {
1104             const GLvoid *src = _mesa_image_address(dims, srcPacking,
1105                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1106             GLuint *dst = (GLuint *) dstRow;
1107             GLint i;
1108             _mesa_unpack_depth_span(ctx, srcWidth,
1109                                     GL_UNSIGNED_INT, dst,
1110                                     depthScale, srcType, src, srcPacking);
1111             for (i = 0; i < srcWidth; i++)
1112                dst[i] <<= 8;
1113             dstRow += dstRowStride;
1114          }
1115       }
1116    }
1117    return GL_TRUE;
1118 }
1119
1120
1121 /**
1122  * Store a 16-bit integer depth component texture image.
1123  */
1124 static GLboolean
1125 _mesa_texstore_z16(TEXSTORE_PARAMS)
1126 {
1127    const GLuint depthScale = 0xffff;
1128    (void) dims;
1129    ASSERT(dstFormat == MESA_FORMAT_Z16);
1130    ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
1131
1132    if (ctx->Pixel.DepthScale == 1.0f &&
1133        ctx->Pixel.DepthBias == 0.0f &&
1134        !srcPacking->SwapBytes &&
1135        baseInternalFormat == GL_DEPTH_COMPONENT &&
1136        srcFormat == GL_DEPTH_COMPONENT &&
1137        srcType == GL_UNSIGNED_SHORT) {
1138       /* simple memcpy path */
1139       memcpy_texture(ctx, dims,
1140                      dstFormat,
1141                      dstRowStride, dstSlices,
1142                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1143                      srcAddr, srcPacking);
1144    }
1145    else {
1146       /* general path */
1147       GLint img, row;
1148       for (img = 0; img < srcDepth; img++) {
1149          GLubyte *dstRow = dstSlices[img];
1150          for (row = 0; row < srcHeight; row++) {
1151             const GLvoid *src = _mesa_image_address(dims, srcPacking,
1152                 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1153             GLushort *dst16 = (GLushort *) dstRow;
1154             _mesa_unpack_depth_span(ctx, srcWidth,
1155                                     GL_UNSIGNED_SHORT, dst16, depthScale,
1156                                     srcType, src, srcPacking);
1157             dstRow += dstRowStride;
1158          }
1159       }
1160    }
1161    return GL_TRUE;
1162 }
1163
1164
1165 /**
1166  * Store an rgb565 or rgb565_rev texture image.
1167  */
1168 static GLboolean
1169 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1170 {
1171    ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
1172           dstFormat == MESA_FORMAT_RGB565_REV);
1173    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1174
1175    if (!ctx->_ImageTransferState &&
1176        baseInternalFormat == GL_RGB &&
1177        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1178                                             srcPacking->SwapBytes)) {
1179       /* simple memcpy path */
1180       memcpy_texture(ctx, dims,
1181                      dstFormat,
1182                      dstRowStride, dstSlices,
1183                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1184                      srcAddr, srcPacking);
1185    }
1186    else if (!ctx->_ImageTransferState &&
1187             !srcPacking->SwapBytes &&
1188             baseInternalFormat == GL_RGB &&
1189             srcFormat == GL_RGB &&
1190             srcType == GL_UNSIGNED_BYTE &&
1191             dims == 2) {
1192       /* do optimized tex store */
1193       const GLint srcRowStride =
1194          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1195       const GLubyte *src = (const GLubyte *)
1196          _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1197                              srcFormat, srcType, 0, 0, 0);
1198       GLubyte *dst = dstSlices[0];
1199       GLint row, col;
1200       for (row = 0; row < srcHeight; row++) {
1201          const GLubyte *srcUB = (const GLubyte *) src;
1202          GLushort *dstUS = (GLushort *) dst;
1203          /* check for byteswapped format */
1204          if (dstFormat == MESA_FORMAT_RGB565) {
1205             for (col = 0; col < srcWidth; col++) {
1206                dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1207                srcUB += 3;
1208             }
1209          }
1210          else {
1211             for (col = 0; col < srcWidth; col++) {
1212                dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1213                srcUB += 3;
1214             }
1215          }
1216          dst += dstRowStride;
1217          src += srcRowStride;
1218       }
1219    }
1220    else {
1221       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1222                                  dstFormat, dstRowStride, dstSlices,
1223                                  srcWidth, srcHeight, srcDepth,
1224                                  srcFormat, srcType, srcAddr, srcPacking);
1225    }
1226    return GL_TRUE;
1227 }
1228
1229
1230 /**
1231  * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1232  */
1233 static GLboolean
1234 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1235 {
1236    const GLboolean littleEndian = _mesa_little_endian();
1237
1238    ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
1239           dstFormat == MESA_FORMAT_RGBA8888_REV ||
1240           dstFormat == MESA_FORMAT_RGBX8888 ||
1241           dstFormat == MESA_FORMAT_RGBX8888_REV);
1242    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1243
1244    if (!ctx->_ImageTransferState &&
1245        baseInternalFormat == GL_RGBA &&
1246        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1247                                             srcPacking->SwapBytes)) {
1248       /* simple memcpy path */
1249       memcpy_texture(ctx, dims,
1250                      dstFormat,
1251                      dstRowStride, dstSlices,
1252                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1253                      srcAddr, srcPacking);
1254    }
1255    else if (!ctx->_ImageTransferState &&
1256             (srcType == GL_UNSIGNED_BYTE ||
1257              srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1258              srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1259             can_swizzle(baseInternalFormat) &&
1260             can_swizzle(srcFormat)) {
1261
1262       GLubyte dstmap[4];
1263
1264       /* dstmap - how to swizzle from RGBA to dst format:
1265        */
1266       if ((littleEndian && (dstFormat == MESA_FORMAT_RGBA8888 ||
1267                             dstFormat == MESA_FORMAT_RGBX8888)) ||
1268           (!littleEndian && (dstFormat == MESA_FORMAT_RGBA8888_REV ||
1269                              dstFormat == MESA_FORMAT_RGBX8888_REV))) {
1270          dstmap[3] = 0;
1271          dstmap[2] = 1;
1272          dstmap[1] = 2;
1273          dstmap[0] = 3;
1274       }
1275       else {
1276          dstmap[3] = 3;
1277          dstmap[2] = 2;
1278          dstmap[1] = 1;
1279          dstmap[0] = 0;
1280       }
1281       
1282       _mesa_swizzle_ubyte_image(ctx, dims,
1283                                 srcFormat,
1284                                 srcType,
1285                                 baseInternalFormat,
1286                                 dstmap, 4,
1287                                 dstRowStride, dstSlices,
1288                                 srcWidth, srcHeight, srcDepth, srcAddr,
1289                                 srcPacking);      
1290    }
1291    else {
1292       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1293                                  dstFormat, dstRowStride, dstSlices,
1294                                  srcWidth, srcHeight, srcDepth,
1295                                  srcFormat, srcType, srcAddr, srcPacking);
1296    }
1297    return GL_TRUE;
1298 }
1299
1300
1301 static GLboolean
1302 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1303 {
1304    const GLboolean littleEndian = _mesa_little_endian();
1305
1306    ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
1307           dstFormat == MESA_FORMAT_ARGB8888_REV ||
1308           dstFormat == MESA_FORMAT_XRGB8888 ||
1309           dstFormat == MESA_FORMAT_XRGB8888_REV );
1310    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1311
1312    if (!ctx->_ImageTransferState &&
1313        baseInternalFormat == GL_RGBA &&
1314        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1315                                             srcPacking->SwapBytes)) {
1316       /* simple memcpy path (big endian) */
1317       memcpy_texture(ctx, dims,
1318                      dstFormat,
1319                      dstRowStride, dstSlices,
1320                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1321                      srcAddr, srcPacking);
1322    }
1323    else if (!ctx->_ImageTransferState &&
1324             !srcPacking->SwapBytes &&
1325             (dstFormat == MESA_FORMAT_ARGB8888 ||
1326              dstFormat == MESA_FORMAT_XRGB8888) &&
1327             srcFormat == GL_RGB &&
1328             (baseInternalFormat == GL_RGBA ||
1329              baseInternalFormat == GL_RGB) &&
1330             srcType == GL_UNSIGNED_BYTE) {
1331       int img, row, col;
1332       for (img = 0; img < srcDepth; img++) {
1333          const GLint srcRowStride =
1334             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1335          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1336                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1337          GLubyte *dstRow = dstSlices[img];
1338          for (row = 0; row < srcHeight; row++) {
1339             GLuint *d4 = (GLuint *) dstRow;
1340             for (col = 0; col < srcWidth; col++) {
1341                d4[col] = PACK_COLOR_8888(0xff,
1342                                          srcRow[col * 3 + RCOMP],
1343                                          srcRow[col * 3 + GCOMP],
1344                                          srcRow[col * 3 + BCOMP]);
1345             }
1346             dstRow += dstRowStride;
1347             srcRow += srcRowStride;
1348          }
1349       }
1350    }
1351    else if (!ctx->_ImageTransferState &&
1352             !srcPacking->SwapBytes &&
1353             dstFormat == MESA_FORMAT_ARGB8888 &&
1354             srcFormat == GL_LUMINANCE_ALPHA &&
1355             baseInternalFormat == GL_RGBA &&
1356             srcType == GL_UNSIGNED_BYTE) {
1357       /* special case of storing LA -> ARGB8888 */
1358       int img, row, col;
1359       const GLint srcRowStride =
1360          _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1361       for (img = 0; img < srcDepth; img++) {
1362          const GLubyte *srcRow = (const GLubyte *)
1363             _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
1364                                 srcHeight, srcFormat, srcType, img, 0, 0);
1365          GLubyte *dstRow = dstSlices[img];
1366          for (row = 0; row < srcHeight; row++) {
1367             GLuint *d4 = (GLuint *) dstRow;
1368             for (col = 0; col < srcWidth; col++) {
1369                GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
1370                d4[col] = PACK_COLOR_8888(a, l, l, l);
1371             }
1372             dstRow += dstRowStride;
1373             srcRow += srcRowStride;
1374          }
1375       }
1376    }
1377    else if (!ctx->_ImageTransferState &&
1378             !srcPacking->SwapBytes &&
1379             dstFormat == MESA_FORMAT_ARGB8888 &&
1380             srcFormat == GL_RGBA &&
1381             baseInternalFormat == GL_RGBA &&
1382             srcType == GL_UNSIGNED_BYTE) {
1383       /* same as above case, but src data has alpha too */
1384       GLint img, row, col;
1385       /* For some reason, streaming copies to write-combined regions
1386        * are extremely sensitive to the characteristics of how the
1387        * source data is retrieved.  By reordering the source reads to
1388        * be in-order, the speed of this operation increases by half.
1389        * Strangely the same isn't required for the RGB path, above.
1390        */
1391       for (img = 0; img < srcDepth; img++) {
1392          const GLint srcRowStride =
1393             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1394          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1395                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1396          GLubyte *dstRow = dstSlices[img];
1397          for (row = 0; row < srcHeight; row++) {
1398             GLuint *d4 = (GLuint *) dstRow;
1399             for (col = 0; col < srcWidth; col++) {
1400                d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1401                                          srcRow[col * 4 + RCOMP],
1402                                          srcRow[col * 4 + GCOMP],
1403                                          srcRow[col * 4 + BCOMP]);
1404             }
1405             dstRow += dstRowStride;
1406             srcRow += srcRowStride;
1407          }
1408       }
1409    }
1410    else if (!ctx->_ImageTransferState &&
1411             (srcType == GL_UNSIGNED_BYTE ||
1412              srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1413              srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1414             can_swizzle(baseInternalFormat) &&     
1415             can_swizzle(srcFormat)) {
1416
1417       GLubyte dstmap[4];
1418
1419       /* dstmap - how to swizzle from RGBA to dst format:
1420        */
1421       if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1422           (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1423           (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1424           (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV)) {
1425          dstmap[3] = 3;         /* alpha */
1426          dstmap[2] = 0;         /* red */
1427          dstmap[1] = 1;         /* green */
1428          dstmap[0] = 2;         /* blue */
1429       }
1430       else {
1431          assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1432                 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1433                 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888_REV) ||
1434                 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1435          dstmap[3] = 2;
1436          dstmap[2] = 1;
1437          dstmap[1] = 0;
1438          dstmap[0] = 3;
1439       }
1440  
1441       _mesa_swizzle_ubyte_image(ctx, dims,
1442                                 srcFormat,
1443                                 srcType,
1444                                 baseInternalFormat,
1445                                 dstmap, 4,
1446                                 dstRowStride,
1447                                 dstSlices,
1448                                 srcWidth, srcHeight, srcDepth, srcAddr,
1449                                 srcPacking);      
1450    }
1451    else {
1452       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1453                                  dstFormat, dstRowStride, dstSlices,
1454                                  srcWidth, srcHeight, srcDepth,
1455                                  srcFormat, srcType, srcAddr, srcPacking);
1456    }
1457    return GL_TRUE;
1458 }
1459
1460
1461 static GLboolean
1462 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1463 {
1464    ASSERT(dstFormat == MESA_FORMAT_RGB888);
1465    ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1466
1467    if (!ctx->_ImageTransferState &&
1468        baseInternalFormat == GL_RGB &&
1469        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1470                                             srcPacking->SwapBytes)) {
1471       /* simple memcpy path */
1472       memcpy_texture(ctx, dims,
1473                      dstFormat,
1474                      dstRowStride, dstSlices,
1475                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1476                      srcAddr, srcPacking);
1477    }
1478    else if (!ctx->_ImageTransferState &&
1479             !srcPacking->SwapBytes &&
1480             srcFormat == GL_RGBA &&
1481             srcType == GL_UNSIGNED_BYTE) {
1482       /* extract RGB from RGBA */
1483       GLint img, row, col;
1484       for (img = 0; img < srcDepth; img++) {
1485          const GLint srcRowStride =
1486             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1487          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1488                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1489          GLubyte *dstRow = dstSlices[img];
1490          for (row = 0; row < srcHeight; row++) {
1491             for (col = 0; col < srcWidth; col++) {
1492                dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1493                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1494                dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1495             }
1496             dstRow += dstRowStride;
1497             srcRow += srcRowStride;
1498          }
1499       }
1500    }
1501    else if (!ctx->_ImageTransferState &&
1502             srcType == GL_UNSIGNED_BYTE &&
1503             can_swizzle(baseInternalFormat) &&
1504             can_swizzle(srcFormat)) {
1505
1506       GLubyte dstmap[4];
1507
1508       /* dstmap - how to swizzle from RGBA to dst format:
1509        */
1510       dstmap[0] = 2;
1511       dstmap[1] = 1;
1512       dstmap[2] = 0;
1513       dstmap[3] = ONE;          /* ? */
1514       
1515       _mesa_swizzle_ubyte_image(ctx, dims,
1516                                 srcFormat,
1517                                 srcType,
1518                                 baseInternalFormat,
1519                                 dstmap, 3,
1520                                 dstRowStride, dstSlices,
1521                                 srcWidth, srcHeight, srcDepth, srcAddr,
1522                                 srcPacking);      
1523    }
1524    else {
1525       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1526                                  dstFormat, dstRowStride, dstSlices,
1527                                  srcWidth, srcHeight, srcDepth,
1528                                  srcFormat, srcType, srcAddr, srcPacking);
1529    }
1530    return GL_TRUE;
1531 }
1532
1533
1534 static GLboolean
1535 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1536 {
1537    ASSERT(dstFormat == MESA_FORMAT_BGR888);
1538    ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1539
1540    if (!ctx->_ImageTransferState &&
1541        baseInternalFormat == GL_RGB &&
1542        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1543                                             srcPacking->SwapBytes)) {
1544       /* simple memcpy path */
1545       memcpy_texture(ctx, dims,
1546                      dstFormat,
1547                      dstRowStride, dstSlices,
1548                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1549                      srcAddr, srcPacking);
1550    }
1551    else if (!ctx->_ImageTransferState &&
1552             !srcPacking->SwapBytes &&
1553             srcFormat == GL_RGBA &&
1554             srcType == GL_UNSIGNED_BYTE) {
1555       /* extract BGR from RGBA */
1556       int img, row, col;
1557       for (img = 0; img < srcDepth; img++) {
1558          const GLint srcRowStride =
1559             _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1560          GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1561                   srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1562          GLubyte *dstRow = dstSlices[img];
1563          for (row = 0; row < srcHeight; row++) {
1564             for (col = 0; col < srcWidth; col++) {
1565                dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1566                dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1567                dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1568             }
1569             dstRow += dstRowStride;
1570             srcRow += srcRowStride;
1571          }
1572       }
1573    }
1574    else if (!ctx->_ImageTransferState &&
1575             srcType == GL_UNSIGNED_BYTE &&
1576             can_swizzle(baseInternalFormat) &&
1577             can_swizzle(srcFormat)) {
1578
1579       GLubyte dstmap[4];
1580
1581       /* dstmap - how to swizzle from RGBA to dst format:
1582        */
1583       dstmap[0] = 0;
1584       dstmap[1] = 1;
1585       dstmap[2] = 2;
1586       dstmap[3] = ONE;          /* ? */
1587       
1588       _mesa_swizzle_ubyte_image(ctx, dims,
1589                                 srcFormat,
1590                                 srcType,
1591                                 baseInternalFormat,
1592                                 dstmap, 3,
1593                                 dstRowStride, dstSlices,
1594                                 srcWidth, srcHeight, srcDepth, srcAddr,
1595                                 srcPacking);      
1596    }   
1597    else {
1598       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1599                                  dstFormat, dstRowStride, dstSlices,
1600                                  srcWidth, srcHeight, srcDepth,
1601                                  srcFormat, srcType, srcAddr, srcPacking);
1602    }
1603    return GL_TRUE;
1604 }
1605
1606
1607 static GLboolean
1608 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1609 {
1610    ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1611           dstFormat == MESA_FORMAT_ARGB4444_REV);
1612    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1613
1614    if (!ctx->_ImageTransferState &&
1615        baseInternalFormat == GL_RGBA &&
1616        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1617                                             srcPacking->SwapBytes)) {
1618       /* simple memcpy path */
1619       memcpy_texture(ctx, dims,
1620                      dstFormat,
1621                      dstRowStride, dstSlices,
1622                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1623                      srcAddr, srcPacking);
1624    }
1625    else {
1626       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1627                                  dstFormat, dstRowStride, dstSlices,
1628                                  srcWidth, srcHeight, srcDepth,
1629                                  srcFormat, srcType, srcAddr, srcPacking);
1630    }
1631    return GL_TRUE;
1632 }
1633
1634 static GLboolean
1635 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1636 {
1637    ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1638    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1639
1640    if (!ctx->_ImageTransferState &&
1641        baseInternalFormat == GL_RGBA &&
1642        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1643                                             srcPacking->SwapBytes)) {
1644       /* simple memcpy path */
1645       memcpy_texture(ctx, dims,
1646                      dstFormat,
1647                      dstRowStride, dstSlices,
1648                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1649                      srcAddr, srcPacking);
1650    }
1651    else {
1652       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1653                                  dstFormat, dstRowStride, dstSlices,
1654                                  srcWidth, srcHeight, srcDepth,
1655                                  srcFormat, srcType, srcAddr, srcPacking);
1656    }
1657    return GL_TRUE;
1658 }
1659
1660 static GLboolean
1661 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
1662 {
1663    ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1664           dstFormat == MESA_FORMAT_ARGB1555_REV);
1665    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1666
1667    if (!ctx->_ImageTransferState &&
1668        baseInternalFormat == GL_RGBA &&
1669        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1670                                             srcPacking->SwapBytes)) {
1671       /* simple memcpy path */
1672       memcpy_texture(ctx, dims,
1673                      dstFormat,
1674                      dstRowStride, dstSlices,
1675                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1676                      srcAddr, srcPacking);
1677    }
1678    else {
1679       return store_ubyte_texture(ctx, dims, baseInternalFormat,
1680                                  dstFormat, dstRowStride, dstSlices,
1681                                  srcWidth, srcHeight, srcDepth,
1682                                  srcFormat, srcType, srcAddr, srcPacking);
1683    }
1684    return GL_TRUE;
1685 }
1686
1687
1688 static GLboolean
1689 _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
1690 {
1691    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1692
1693    ASSERT(dstFormat == MESA_FORMAT_ARGB2101010);
1694    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1695
1696    if (!ctx->_ImageTransferState &&
1697        baseInternalFormat == GL_RGBA &&
1698        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
1699                                             srcPacking->SwapBytes)) {
1700       /* simple memcpy path */
1701       memcpy_texture(ctx, dims,
1702                      dstFormat,
1703                      dstRowStride, dstSlices,
1704                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1705                      srcAddr, srcPacking);
1706    }
1707    else {
1708       /* general path */
1709       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1710                                                  baseInternalFormat,
1711                                                  baseFormat,
1712                                                  srcWidth, srcHeight, srcDepth,
1713                                                  srcFormat, srcType, srcAddr,
1714                                                  srcPacking,
1715                                                  ctx->_ImageTransferState);
1716       const GLfloat *src = tempImage;
1717       GLint img, row, col;
1718       if (!tempImage)
1719          return GL_FALSE;
1720       for (img = 0; img < srcDepth; img++) {
1721          GLubyte *dstRow = dstSlices[img];
1722          if (baseInternalFormat == GL_RGBA) {
1723             for (row = 0; row < srcHeight; row++) {
1724                GLuint *dstUI = (GLuint *) dstRow;
1725                for (col = 0; col < srcWidth; col++) {
1726                   GLushort a,r,g,b;
1727
1728                   UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
1729                   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
1730                   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
1731                   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
1732                   dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
1733                   src += 4;
1734                }
1735                dstRow += dstRowStride;
1736             }
1737          } else if (baseInternalFormat == GL_RGB) {
1738             for (row = 0; row < srcHeight; row++) {
1739                GLuint *dstUI = (GLuint *) dstRow;
1740                for (col = 0; col < srcWidth; col++) {
1741                   GLushort r,g,b;
1742
1743                   UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
1744                   UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
1745                   UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
1746                   dstUI[col] = PACK_COLOR_2101010_US(0xffff, r, g, b);
1747                   src += 4;
1748                }
1749                dstRow += dstRowStride;
1750             }
1751          } else {
1752             ASSERT(0);
1753          }
1754       }
1755       free((void *) tempImage);
1756    }
1757    return GL_TRUE;
1758 }
1759
1760
1761 /**
1762  * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
1763  */
1764 static GLboolean
1765 _mesa_texstore_unorm44(TEXSTORE_PARAMS)
1766 {
1767    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1768
1769    ASSERT(dstFormat == MESA_FORMAT_AL44);
1770    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
1771
1772    {
1773       /* general path */
1774       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1775                                                  baseInternalFormat,
1776                                                  baseFormat,
1777                                                  srcWidth, srcHeight, srcDepth,
1778                                                  srcFormat, srcType, srcAddr,
1779                                                  srcPacking);
1780       const GLubyte *src = tempImage;
1781       GLint img, row, col;
1782       if (!tempImage)
1783          return GL_FALSE;
1784       for (img = 0; img < srcDepth; img++) {
1785          GLubyte *dstRow = dstSlices[img];
1786          for (row = 0; row < srcHeight; row++) {
1787             GLubyte *dstUS = (GLubyte *) dstRow;
1788             for (col = 0; col < srcWidth; col++) {
1789                /* src[0] is luminance, src[1] is alpha */
1790                dstUS[col] = PACK_COLOR_44( src[1],
1791                                            src[0] );
1792                src += 2;
1793             }
1794             dstRow += dstRowStride;
1795          }
1796       }
1797       free((void *) tempImage);
1798    }
1799    return GL_TRUE;
1800 }
1801
1802
1803 /**
1804  * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
1805  */
1806 static GLboolean
1807 _mesa_texstore_unorm88(TEXSTORE_PARAMS)
1808 {
1809    const GLboolean littleEndian = _mesa_little_endian();
1810    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1811
1812    ASSERT(dstFormat == MESA_FORMAT_AL88 ||
1813           dstFormat == MESA_FORMAT_AL88_REV ||
1814           dstFormat == MESA_FORMAT_GR88 ||
1815           dstFormat == MESA_FORMAT_RG88);
1816    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1817
1818    if (!ctx->_ImageTransferState &&
1819        !srcPacking->SwapBytes &&
1820        ((dstFormat == MESA_FORMAT_AL88 &&
1821          baseInternalFormat == GL_LUMINANCE_ALPHA &&
1822          srcFormat == GL_LUMINANCE_ALPHA) ||
1823         (dstFormat == MESA_FORMAT_GR88 &&
1824          baseInternalFormat == srcFormat)) &&
1825        srcType == GL_UNSIGNED_BYTE &&
1826        littleEndian) {
1827       /* simple memcpy path */
1828       memcpy_texture(ctx, dims,
1829                      dstFormat,
1830                      dstRowStride, dstSlices,
1831                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1832                      srcAddr, srcPacking);
1833    }
1834    else if (!ctx->_ImageTransferState &&
1835             littleEndian &&
1836             srcType == GL_UNSIGNED_BYTE &&
1837             can_swizzle(baseInternalFormat) &&
1838             can_swizzle(srcFormat)) {
1839       GLubyte dstmap[4];
1840
1841       /* dstmap - how to swizzle from RGBA to dst format:
1842        */
1843       if (dstFormat == MESA_FORMAT_AL88 || dstFormat == MESA_FORMAT_AL88_REV) {
1844          if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
1845              (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
1846             dstmap[0] = 0;
1847             dstmap[1] = 3;
1848          }
1849          else {
1850             dstmap[0] = 3;
1851             dstmap[1] = 0;
1852          }
1853       }
1854       else {
1855          if ((littleEndian && dstFormat == MESA_FORMAT_GR88) ||
1856              (!littleEndian && dstFormat == MESA_FORMAT_RG88)) {
1857             dstmap[0] = 0;
1858             dstmap[1] = 1;
1859          }
1860          else {
1861             dstmap[0] = 1;
1862             dstmap[1] = 0;
1863          }
1864       }
1865       dstmap[2] = ZERO;         /* ? */
1866       dstmap[3] = ONE;          /* ? */
1867       
1868       _mesa_swizzle_ubyte_image(ctx, dims,
1869                                 srcFormat,
1870                                 srcType,
1871                                 baseInternalFormat,
1872                                 dstmap, 2,
1873                                 dstRowStride, dstSlices,
1874                                 srcWidth, srcHeight, srcDepth, srcAddr,
1875                                 srcPacking);      
1876    }   
1877    else {
1878       /* general path */
1879       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1880                                                  baseInternalFormat,
1881                                                  baseFormat,
1882                                                  srcWidth, srcHeight, srcDepth,
1883                                                  srcFormat, srcType, srcAddr,
1884                                                  srcPacking);
1885       const GLubyte *src = tempImage;
1886       GLint img, row, col;
1887       if (!tempImage)
1888          return GL_FALSE;
1889       for (img = 0; img < srcDepth; img++) {
1890          GLubyte *dstRow = dstSlices[img];
1891          for (row = 0; row < srcHeight; row++) {
1892             GLushort *dstUS = (GLushort *) dstRow;
1893             if (dstFormat == MESA_FORMAT_AL88 ||
1894                 dstFormat == MESA_FORMAT_GR88) {
1895                for (col = 0; col < srcWidth; col++) {
1896                   /* src[0] is luminance (or R), src[1] is alpha (or G) */
1897                  dstUS[col] = PACK_COLOR_88( src[1],
1898                                              src[0] );
1899                  src += 2;
1900                }
1901             }
1902             else {
1903                for (col = 0; col < srcWidth; col++) {
1904                   /* src[0] is luminance (or R), src[1] is alpha (or G) */
1905                  dstUS[col] = PACK_COLOR_88_REV( src[1],
1906                                                  src[0] );
1907                  src += 2;
1908                }
1909             }
1910             dstRow += dstRowStride;
1911          }
1912       }
1913       free((void *) tempImage);
1914    }
1915    return GL_TRUE;
1916 }
1917
1918
1919 /**
1920  * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
1921  */
1922 static GLboolean
1923 _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
1924 {
1925    const GLboolean littleEndian = _mesa_little_endian();
1926    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1927
1928    ASSERT(dstFormat == MESA_FORMAT_AL1616 ||
1929           dstFormat == MESA_FORMAT_AL1616_REV ||
1930           dstFormat == MESA_FORMAT_RG1616 ||
1931           dstFormat == MESA_FORMAT_RG1616_REV);
1932    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1933
1934    if (!ctx->_ImageTransferState &&
1935        !srcPacking->SwapBytes &&
1936        ((dstFormat == MESA_FORMAT_AL1616 &&
1937          baseInternalFormat == GL_LUMINANCE_ALPHA &&
1938          srcFormat == GL_LUMINANCE_ALPHA) ||
1939         (dstFormat == MESA_FORMAT_RG1616 &&
1940          baseInternalFormat == srcFormat)) &&
1941        srcType == GL_UNSIGNED_SHORT &&
1942        littleEndian) {
1943       /* simple memcpy path */
1944       memcpy_texture(ctx, dims,
1945                      dstFormat,
1946                      dstRowStride, dstSlices,
1947                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1948                      srcAddr, srcPacking);
1949    }
1950    else {
1951       /* general path */
1952       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1953                                                  baseInternalFormat,
1954                                                  baseFormat,
1955                                                  srcWidth, srcHeight, srcDepth,
1956                                                  srcFormat, srcType, srcAddr,
1957                                                  srcPacking,
1958                                                  ctx->_ImageTransferState);
1959       const GLfloat *src = tempImage;
1960       GLint img, row, col;
1961       if (!tempImage)
1962          return GL_FALSE;
1963       for (img = 0; img < srcDepth; img++) {
1964          GLubyte *dstRow = dstSlices[img];
1965          for (row = 0; row < srcHeight; row++) {
1966             GLuint *dstUI = (GLuint *) dstRow;
1967             if (dstFormat == MESA_FORMAT_AL1616 ||
1968                 dstFormat == MESA_FORMAT_RG1616) {
1969                for (col = 0; col < srcWidth; col++) {
1970                   GLushort l, a;
1971
1972                   UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1973                   UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1974                   dstUI[col] = PACK_COLOR_1616(a, l);
1975                   src += 2;
1976                }
1977             }
1978             else {
1979                for (col = 0; col < srcWidth; col++) {
1980                   GLushort l, a;
1981
1982                   UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1983                   UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1984                   dstUI[col] = PACK_COLOR_1616_REV(a, l);
1985                   src += 2;
1986                }
1987             }
1988             dstRow += dstRowStride;
1989          }
1990       }
1991       free((void *) tempImage);
1992    }
1993    return GL_TRUE;
1994 }
1995
1996
1997 /* Texstore for R16, A16, L16, I16. */
1998 static GLboolean
1999 _mesa_texstore_unorm16(TEXSTORE_PARAMS)
2000 {
2001    const GLboolean littleEndian = _mesa_little_endian();
2002    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2003
2004    ASSERT(dstFormat == MESA_FORMAT_R16 ||
2005           dstFormat == MESA_FORMAT_A16 ||
2006           dstFormat == MESA_FORMAT_L16 ||
2007           dstFormat == MESA_FORMAT_I16);
2008    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2009
2010    if (!ctx->_ImageTransferState &&
2011        !srcPacking->SwapBytes &&
2012        baseInternalFormat == srcFormat &&
2013        srcType == GL_UNSIGNED_SHORT &&
2014        littleEndian) {
2015       /* simple memcpy path */
2016       memcpy_texture(ctx, dims,
2017                      dstFormat,
2018                      dstRowStride, dstSlices,
2019                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2020                      srcAddr, srcPacking);
2021    }
2022    else {
2023       /* general path */
2024       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2025                                                  baseInternalFormat,
2026                                                  baseFormat,
2027                                                  srcWidth, srcHeight, srcDepth,
2028                                                  srcFormat, srcType, srcAddr,
2029                                                  srcPacking,
2030                                                  ctx->_ImageTransferState);
2031       const GLfloat *src = tempImage;
2032       GLint img, row, col;
2033       if (!tempImage)
2034          return GL_FALSE;
2035       for (img = 0; img < srcDepth; img++) {
2036          GLubyte *dstRow = dstSlices[img];
2037          for (row = 0; row < srcHeight; row++) {
2038             GLushort *dstUS = (GLushort *) dstRow;
2039             for (col = 0; col < srcWidth; col++) {
2040                GLushort r;
2041
2042                UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2043                dstUS[col] = r;
2044                src += 1;
2045             }
2046             dstRow += dstRowStride;
2047          }
2048       }
2049       free((void *) tempImage);
2050    }
2051    return GL_TRUE;
2052 }
2053
2054
2055 static GLboolean
2056 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
2057 {
2058    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2059
2060    ASSERT(dstFormat == MESA_FORMAT_RGBA_16);
2061    ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
2062
2063    if (!ctx->_ImageTransferState &&
2064        !srcPacking->SwapBytes &&
2065        baseInternalFormat == GL_RGBA &&
2066        srcFormat == GL_RGBA &&
2067        srcType == GL_UNSIGNED_SHORT) {
2068       /* simple memcpy path */
2069       memcpy_texture(ctx, dims,
2070                      dstFormat,
2071                      dstRowStride, dstSlices,
2072                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2073                      srcAddr, srcPacking);
2074    }
2075    else {
2076       /* general path */
2077       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2078                                                  baseInternalFormat,
2079                                                  baseFormat,
2080                                                  srcWidth, srcHeight, srcDepth,
2081                                                  srcFormat, srcType, srcAddr,
2082                                                  srcPacking,
2083                                                  ctx->_ImageTransferState);
2084       const GLfloat *src = tempImage;
2085       GLint img, row, col;
2086       if (!tempImage)
2087          return GL_FALSE;
2088       for (img = 0; img < srcDepth; img++) {
2089          GLubyte *dstRow = dstSlices[img];
2090          for (row = 0; row < srcHeight; row++) {
2091             GLushort *dstUS = (GLushort *) dstRow;
2092             for (col = 0; col < srcWidth; col++) {
2093                GLushort r, g, b, a;
2094
2095                UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
2096                UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
2097                UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
2098                UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
2099                dstUS[col*4+0] = r;
2100                dstUS[col*4+1] = g;
2101                dstUS[col*4+2] = b;
2102                dstUS[col*4+3] = a;
2103                src += 4;
2104             }
2105             dstRow += dstRowStride;
2106          }
2107       }
2108       free((void *) tempImage);
2109    }
2110    return GL_TRUE;
2111 }
2112
2113
2114 static GLboolean
2115 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
2116 {
2117    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2118
2119    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGB_16 ||
2120           dstFormat == MESA_FORMAT_SIGNED_RGBA_16);
2121
2122    if (!ctx->_ImageTransferState &&
2123        !srcPacking->SwapBytes &&
2124        baseInternalFormat == GL_RGBA &&
2125        dstFormat == MESA_FORMAT_SIGNED_RGBA_16 &&
2126        srcFormat == GL_RGBA &&
2127        srcType == GL_SHORT) {
2128       /* simple memcpy path */
2129       memcpy_texture(ctx, dims,
2130                      dstFormat,
2131                      dstRowStride, dstSlices,
2132                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2133                      srcAddr, srcPacking);
2134    }
2135    else {
2136       /* general path */
2137       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2138                                                  baseInternalFormat,
2139                                                  baseFormat,
2140                                                  srcWidth, srcHeight, srcDepth,
2141                                                  srcFormat, srcType, srcAddr,
2142                                                  srcPacking,
2143                                                  ctx->_ImageTransferState);
2144       const GLfloat *src = tempImage;
2145       const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
2146       GLint img, row, col;
2147
2148       if (!tempImage)
2149          return GL_FALSE;
2150
2151       /* Note: tempImage is always float[4] / RGBA.  We convert to 1, 2,
2152        * 3 or 4 components/pixel here.
2153        */
2154       for (img = 0; img < srcDepth; img++) {
2155          GLubyte *dstRow = dstSlices[img];
2156          for (row = 0; row < srcHeight; row++) {
2157             GLshort *dstRowS = (GLshort *) dstRow;
2158             if (dstFormat == MESA_FORMAT_SIGNED_RGBA_16) {
2159                for (col = 0; col < srcWidth; col++) {
2160                   GLuint c;
2161                   for (c = 0; c < comps; c++) {
2162                      GLshort p;
2163                      UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
2164                      dstRowS[col * comps + c] = p;
2165                   }
2166                }
2167                dstRow += dstRowStride;
2168                src += 4 * srcWidth;
2169             } else {
2170                for (col = 0; col < srcWidth; col++) {
2171                   GLuint c;
2172                   for (c = 0; c < comps; c++) {
2173                      GLshort p;
2174                      UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
2175                      dstRowS[col * comps + c] = p;
2176                   }
2177                }
2178                dstRow += dstRowStride;
2179                src += 3 * srcWidth;
2180             }
2181          }
2182       }
2183       free((void *) tempImage);
2184    }
2185    return GL_TRUE;
2186 }
2187
2188
2189 static GLboolean
2190 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2191 {
2192    ASSERT(dstFormat == MESA_FORMAT_RGB332);
2193    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2194
2195    if (!ctx->_ImageTransferState &&
2196        baseInternalFormat == GL_RGB &&
2197        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
2198                                             srcPacking->SwapBytes)) {
2199       /* simple memcpy path */
2200       memcpy_texture(ctx, dims,
2201                      dstFormat,
2202                      dstRowStride, dstSlices,
2203                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2204                      srcAddr, srcPacking);
2205    }
2206    else {
2207       return store_ubyte_texture(ctx, dims, baseInternalFormat,
2208                                  dstFormat, dstRowStride, dstSlices,
2209                                  srcWidth, srcHeight, srcDepth,
2210                                  srcFormat, srcType, srcAddr, srcPacking);
2211    }
2212    return GL_TRUE;
2213 }
2214
2215
2216 /**
2217  * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2218  */
2219 static GLboolean
2220 _mesa_texstore_unorm8(TEXSTORE_PARAMS)
2221 {
2222    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2223
2224    ASSERT(dstFormat == MESA_FORMAT_A8 ||
2225           dstFormat == MESA_FORMAT_L8 ||
2226           dstFormat == MESA_FORMAT_I8 ||
2227           dstFormat == MESA_FORMAT_R8);
2228    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2229
2230    if (!ctx->_ImageTransferState &&
2231        !srcPacking->SwapBytes &&
2232        baseInternalFormat == srcFormat &&
2233        srcType == GL_UNSIGNED_BYTE) {
2234       /* simple memcpy path */
2235       memcpy_texture(ctx, dims,
2236                      dstFormat,
2237                      dstRowStride, dstSlices,
2238                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2239                      srcAddr, srcPacking);
2240    }
2241    else if (!ctx->_ImageTransferState &&
2242             srcType == GL_UNSIGNED_BYTE &&
2243             can_swizzle(baseInternalFormat) &&
2244             can_swizzle(srcFormat)) {
2245       GLubyte dstmap[4];
2246
2247       /* dstmap - how to swizzle from RGBA to dst format:
2248        */
2249       if (dstFormat == MESA_FORMAT_A8) {
2250          dstmap[0] = 3;
2251       }
2252       else {
2253          dstmap[0] = 0;
2254       }
2255       dstmap[1] = ZERO;         /* ? */
2256       dstmap[2] = ZERO;         /* ? */
2257       dstmap[3] = ONE;          /* ? */
2258       
2259       _mesa_swizzle_ubyte_image(ctx, dims,
2260                                 srcFormat,
2261                                 srcType,
2262                                 baseInternalFormat,
2263                                 dstmap, 1,
2264                                 dstRowStride, dstSlices,
2265                                 srcWidth, srcHeight, srcDepth, srcAddr,
2266                                 srcPacking);      
2267    }   
2268    else {
2269       /* general path */
2270       const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
2271                                                  baseInternalFormat,
2272                                                  baseFormat,
2273                                                  srcWidth, srcHeight, srcDepth,
2274                                                  srcFormat, srcType, srcAddr,
2275                                                  srcPacking);
2276       const GLubyte *src = tempImage;
2277       GLint img, row, col;
2278       if (!tempImage)
2279          return GL_FALSE;
2280       for (img = 0; img < srcDepth; img++) {
2281          GLubyte *dstRow = dstSlices[img];
2282          for (row = 0; row < srcHeight; row++) {
2283             for (col = 0; col < srcWidth; col++) {
2284                dstRow[col] = src[col];
2285             }
2286             dstRow += dstRowStride;
2287             src += srcWidth;
2288          }
2289       }
2290       free((void *) tempImage);
2291    }
2292    return GL_TRUE;
2293 }
2294
2295
2296
2297 /**
2298  * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2299  */
2300 static GLboolean
2301 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2302 {
2303    const GLboolean littleEndian = _mesa_little_endian();
2304
2305    (void) ctx; (void) dims; (void) baseInternalFormat;
2306
2307    ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2308           (dstFormat == MESA_FORMAT_YCBCR_REV));
2309    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2310    ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2311    ASSERT(srcFormat == GL_YCBCR_MESA);
2312    ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2313           (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2314    ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2315
2316    /* always just memcpy since no pixel transfer ops apply */
2317    memcpy_texture(ctx, dims,
2318                   dstFormat,
2319                   dstRowStride, dstSlices,
2320                   srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2321                   srcAddr, srcPacking);
2322
2323    /* Check if we need byte swapping */
2324    /* XXX the logic here _might_ be wrong */
2325    if (srcPacking->SwapBytes ^
2326        (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2327        (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2328        !littleEndian) {
2329       GLint img, row;
2330       for (img = 0; img < srcDepth; img++) {
2331          GLubyte *dstRow = dstSlices[img];
2332          for (row = 0; row < srcHeight; row++) {
2333             _mesa_swap2((GLushort *) dstRow, srcWidth);
2334             dstRow += dstRowStride;
2335          }
2336       }
2337    }
2338    return GL_TRUE;
2339 }
2340
2341 static GLboolean
2342 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2343 {
2344    const GLboolean littleEndian = _mesa_little_endian();
2345    const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2346
2347    ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2348    ASSERT(texelBytes == 2);
2349    ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2350    ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2351           (srcFormat == GL_DUDV_ATI));
2352    ASSERT(baseInternalFormat == GL_DUDV_ATI);
2353
2354    if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2355        littleEndian) {
2356       /* simple memcpy path */
2357       memcpy_texture(ctx, dims,
2358                      dstFormat,
2359                      dstRowStride, dstSlices,
2360                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2361                      srcAddr, srcPacking);
2362    }
2363    else if (srcType == GL_BYTE) {
2364       GLubyte dstmap[4];
2365
2366       /* dstmap - how to swizzle from RGBA to dst format:
2367        */
2368       if (littleEndian) {
2369          dstmap[0] = 0;
2370          dstmap[1] = 3;
2371       }
2372       else {
2373          dstmap[0] = 3;
2374          dstmap[1] = 0;
2375       }
2376       dstmap[2] = ZERO;         /* ? */
2377       dstmap[3] = ONE;          /* ? */
2378       
2379       _mesa_swizzle_ubyte_image(ctx, dims,
2380                                 GL_LUMINANCE_ALPHA, /* hack */
2381                                 GL_UNSIGNED_BYTE, /* hack */
2382                                 GL_LUMINANCE_ALPHA, /* hack */
2383                                 dstmap, 2,
2384                                 dstRowStride, dstSlices,
2385                                 srcWidth, srcHeight, srcDepth, srcAddr,
2386                                 srcPacking);      
2387    }   
2388    else {
2389       /* general path - note this is defined for 2d textures only */
2390       const GLint components = _mesa_components_in_format(baseInternalFormat);
2391       const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2392                                                      srcFormat, srcType);
2393       GLbyte *tempImage, *dst, *src;
2394       GLint row;
2395
2396       tempImage = malloc(srcWidth * srcHeight * srcDepth
2397                                           * components * sizeof(GLbyte));
2398       if (!tempImage)
2399          return GL_FALSE;
2400
2401       src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2402                                            srcWidth, srcHeight,
2403                                            srcFormat, srcType,
2404                                            0, 0, 0);
2405
2406       dst = tempImage;
2407       for (row = 0; row < srcHeight; row++) {
2408          _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2409                                      dst, srcFormat, srcType, src,
2410                                      srcPacking, 0);
2411          dst += srcWidth * components;
2412          src += srcStride;
2413       }
2414  
2415       src = tempImage;
2416       dst = (GLbyte *) dstSlices[0];
2417       for (row = 0; row < srcHeight; row++) {
2418          memcpy(dst, src, srcWidth * texelBytes);
2419          dst += dstRowStride;
2420          src += srcWidth * texelBytes;
2421       }
2422       free((void *) tempImage);
2423    }
2424    return GL_TRUE;
2425 }
2426
2427
2428 /**
2429  * Store a texture in a signed normalized 8-bit format.
2430  */
2431 static GLboolean
2432 _mesa_texstore_snorm8(TEXSTORE_PARAMS)
2433 {
2434    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2435
2436    ASSERT(dstFormat == MESA_FORMAT_SIGNED_A8 ||
2437           dstFormat == MESA_FORMAT_SIGNED_L8 ||
2438           dstFormat == MESA_FORMAT_SIGNED_I8 ||
2439           dstFormat == MESA_FORMAT_SIGNED_R8);
2440    ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2441
2442    if (!ctx->_ImageTransferState &&
2443        !srcPacking->SwapBytes &&
2444        baseInternalFormat == srcFormat &&
2445        srcType == GL_BYTE) {
2446       /* simple memcpy path */
2447       memcpy_texture(ctx, dims,
2448                      dstFormat,
2449                      dstRowStride, dstSlices,
2450                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2451                      srcAddr, srcPacking);
2452    }
2453    else {
2454       /* general path */
2455       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2456                                                  baseInternalFormat,
2457                                                  baseFormat,
2458                                                  srcWidth, srcHeight, srcDepth,
2459                                                  srcFormat, srcType, srcAddr,
2460                                                  srcPacking,
2461                                                  ctx->_ImageTransferState);
2462       const GLfloat *src = tempImage;
2463       GLint img, row, col;
2464       if (!tempImage)
2465          return GL_FALSE;
2466       for (img = 0; img < srcDepth; img++) {
2467          GLbyte *dstRow = (GLbyte *) dstSlices[img];
2468          for (row = 0; row < srcHeight; row++) {
2469             for (col = 0; col < srcWidth; col++) {
2470                dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
2471             }
2472             dstRow += dstRowStride;
2473             src += srcWidth;
2474          }
2475       }
2476       free((void *) tempImage);
2477    }
2478    return GL_TRUE;
2479 }
2480
2481
2482 /**
2483  * Store a texture in a signed normalized two-channel 16-bit format.
2484  */
2485 static GLboolean
2486 _mesa_texstore_snorm88(TEXSTORE_PARAMS)
2487 {
2488    const GLboolean littleEndian = _mesa_little_endian();
2489    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2490
2491    ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL88 ||
2492           dstFormat == MESA_FORMAT_SIGNED_RG88_REV);
2493    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2494
2495    if (!ctx->_ImageTransferState &&
2496        !srcPacking->SwapBytes &&
2497        baseInternalFormat == srcFormat &&
2498        srcType == GL_BYTE &&
2499        littleEndian) {
2500       /* simple memcpy path */
2501       memcpy_texture(ctx, dims,
2502                      dstFormat,
2503                      dstRowStride, dstSlices,
2504                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2505                      srcAddr, srcPacking);
2506    }
2507    else {
2508       /* general path */
2509       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2510                                                  baseInternalFormat,
2511                                                  baseFormat,
2512                                                  srcWidth, srcHeight, srcDepth,
2513                                                  srcFormat, srcType, srcAddr,
2514                                                  srcPacking,
2515                                                  ctx->_ImageTransferState);
2516       const GLfloat *src = tempImage;
2517       GLint img, row, col;
2518       if (!tempImage)
2519          return GL_FALSE;
2520       for (img = 0; img < srcDepth; img++) {
2521          GLbyte *dstRow = (GLbyte *) dstSlices[img];
2522          for (row = 0; row < srcHeight; row++) {
2523             GLbyte *dst = dstRow;
2524             for (col = 0; col < srcWidth; col++) {
2525                dst[0] = FLOAT_TO_BYTE_TEX(src[0]);
2526                dst[1] = FLOAT_TO_BYTE_TEX(src[1]);
2527                src += 2;
2528                dst += 2;
2529             }
2530             dstRow += dstRowStride;
2531          }
2532       }
2533       free((void *) tempImage);
2534    }
2535    return GL_TRUE;
2536 }
2537
2538 /* Texstore for signed R16, A16, L16, I16. */
2539 static GLboolean
2540 _mesa_texstore_snorm16(TEXSTORE_PARAMS)
2541 {
2542    const GLboolean littleEndian = _mesa_little_endian();
2543    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2544
2545    ASSERT(dstFormat == MESA_FORMAT_SIGNED_R16 ||
2546           dstFormat == MESA_FORMAT_SIGNED_A16 ||
2547           dstFormat == MESA_FORMAT_SIGNED_L16 ||
2548           dstFormat == MESA_FORMAT_SIGNED_I16);
2549    ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2550
2551    if (!ctx->_ImageTransferState &&
2552        !srcPacking->SwapBytes &&
2553        baseInternalFormat == srcFormat &&
2554        srcType == GL_SHORT &&
2555        littleEndian) {
2556       /* simple memcpy path */
2557       memcpy_texture(ctx, dims,
2558                      dstFormat,
2559                      dstRowStride, dstSlices,
2560                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2561                      srcAddr, srcPacking);
2562    }
2563    else {
2564       /* general path */
2565       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2566                                                  baseInternalFormat,
2567                                                  baseFormat,
2568                                                  srcWidth, srcHeight, srcDepth,
2569                                                  srcFormat, srcType, srcAddr,
2570                                                  srcPacking,
2571                                                  ctx->_ImageTransferState);
2572       const GLfloat *src = tempImage;
2573       GLint img, row, col;
2574       if (!tempImage)
2575          return GL_FALSE;
2576       for (img = 0; img < srcDepth; img++) {
2577          GLubyte *dstRow = dstSlices[img];
2578          for (row = 0; row < srcHeight; row++) {
2579             GLshort *dstUS = (GLshort *) dstRow;
2580             for (col = 0; col < srcWidth; col++) {
2581                GLushort r;
2582
2583                UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
2584                dstUS[col] = r;
2585                src += 1;
2586             }
2587             dstRow += dstRowStride;
2588          }
2589       }
2590       free((void *) tempImage);
2591    }
2592    return GL_TRUE;
2593 }
2594
2595 /**
2596  * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
2597  */
2598 static GLboolean
2599 _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
2600 {
2601    const GLboolean littleEndian = _mesa_little_endian();
2602    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2603
2604    ASSERT(dstFormat == MESA_FORMAT_SIGNED_AL1616 ||
2605           dstFormat == MESA_FORMAT_SIGNED_GR1616);
2606    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2607
2608    if (!ctx->_ImageTransferState &&
2609        !srcPacking->SwapBytes &&
2610        baseInternalFormat == srcFormat &&
2611        srcType == GL_SHORT &&
2612        littleEndian) {
2613       /* simple memcpy path */
2614       memcpy_texture(ctx, dims,
2615                      dstFormat,
2616                      dstRowStride, dstSlices,
2617                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2618                      srcAddr, srcPacking);
2619    }
2620    else {
2621       /* general path */
2622       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2623                                                  baseInternalFormat,
2624                                                  baseFormat,
2625                                                  srcWidth, srcHeight, srcDepth,
2626                                                  srcFormat, srcType, srcAddr,
2627                                                  srcPacking,
2628                                                  ctx->_ImageTransferState);
2629       const GLfloat *src = tempImage;
2630       GLint img, row, col;
2631       if (!tempImage)
2632          return GL_FALSE;
2633       for (img = 0; img < srcDepth; img++) {
2634          GLubyte *dstRow = dstSlices[img];
2635          for (row = 0; row < srcHeight; row++) {
2636             GLshort *dst = (GLshort *) dstRow;
2637             for (col = 0; col < srcWidth; col++) {
2638                GLushort l, a;
2639
2640                UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
2641                UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
2642                dst[0] = l;
2643                dst[1] = a;
2644                src += 2;
2645                dst += 2;
2646             }
2647             dstRow += dstRowStride;
2648          }
2649       }
2650       free((void *) tempImage);
2651    }
2652    return GL_TRUE;
2653 }
2654
2655 /**
2656  * Store a texture in MESA_FORMAT_SIGNED_RGBX8888.
2657  */
2658 static GLboolean
2659 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
2660 {
2661    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2662
2663    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBX8888);
2664    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2665
2666    {
2667       /* general path */
2668       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2669                                                  baseInternalFormat,
2670                                                  baseFormat,
2671                                                  srcWidth, srcHeight, srcDepth,
2672                                                  srcFormat, srcType, srcAddr,
2673                                                  srcPacking,
2674                                                  ctx->_ImageTransferState);
2675       const GLfloat *srcRow = tempImage;
2676       GLint img, row, col;
2677       if (!tempImage)
2678          return GL_FALSE;
2679       for (img = 0; img < srcDepth; img++) {
2680          GLbyte *dstRow = (GLbyte *) dstSlices[img];
2681          for (row = 0; row < srcHeight; row++) {
2682             GLbyte *dst = dstRow;
2683             for (col = 0; col < srcWidth; col++) {
2684                dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2685                dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2686                dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2687                dst[0] = 127;
2688                srcRow += 3;
2689                dst += 4;
2690             }
2691             dstRow += dstRowStride;
2692          }
2693       }
2694       free((void *) tempImage);
2695    }
2696    return GL_TRUE;
2697 }
2698
2699
2700
2701 /**
2702  * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or
2703  * MESA_FORMAT_SIGNED_RGBA8888_REV
2704  */
2705 static GLboolean
2706 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2707 {
2708    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2709
2710    ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
2711           dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
2712    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2713
2714    if (!ctx->_ImageTransferState &&
2715        baseInternalFormat == GL_RGBA &&
2716        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
2717                                             srcPacking->SwapBytes)) {
2718        /* simple memcpy path */
2719       memcpy_texture(ctx, dims,
2720                      dstFormat,
2721                      dstRowStride, dstSlices,
2722                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2723                      srcAddr, srcPacking);
2724    }
2725    else {
2726       /* general path */
2727       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2728                                                  baseInternalFormat,
2729                                                  baseFormat,
2730                                                  srcWidth, srcHeight, srcDepth,
2731                                                  srcFormat, srcType, srcAddr,
2732                                                  srcPacking,
2733                                                  ctx->_ImageTransferState);
2734       const GLfloat *srcRow = tempImage;
2735       GLint img, row, col;
2736       if (!tempImage)
2737          return GL_FALSE;
2738       for (img = 0; img < srcDepth; img++) {
2739          GLbyte *dstRow = (GLbyte *) dstSlices[img];
2740          for (row = 0; row < srcHeight; row++) {
2741             GLbyte *dst = dstRow;
2742             if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
2743                for (col = 0; col < srcWidth; col++) {
2744                   dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2745                   dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2746                   dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2747                   dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2748                   srcRow += 4;
2749                   dst += 4;
2750                }
2751             }
2752             else {
2753                for (col = 0; col < srcWidth; col++) {
2754                   dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2755                   dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2756                   dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2757                   dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2758                   srcRow += 4;
2759                   dst += 4;
2760                }
2761             }
2762             dstRow += dstRowStride;
2763          }
2764       }
2765       free((void *) tempImage);
2766    }
2767    return GL_TRUE;
2768 }
2769
2770
2771 /**
2772  * Store a combined depth/stencil texture image.
2773  */
2774 static GLboolean
2775 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2776 {
2777    const GLuint depthScale = 0xffffff;
2778    const GLint srcRowStride
2779       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2780    GLint img, row;
2781
2782    ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
2783    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2784           srcFormat == GL_DEPTH_COMPONENT ||
2785           srcFormat == GL_STENCIL_INDEX);
2786    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2787
2788    if (srcFormat == GL_DEPTH_STENCIL && ctx->Pixel.DepthScale == 1.0f &&
2789        ctx->Pixel.DepthBias == 0.0f &&
2790        !srcPacking->SwapBytes) {
2791       /* simple path */
2792       memcpy_texture(ctx, dims,
2793                      dstFormat,
2794                      dstRowStride, dstSlices,
2795                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2796                      srcAddr, srcPacking);
2797    }
2798    else if (srcFormat == GL_DEPTH_COMPONENT ||
2799             srcFormat == GL_STENCIL_INDEX) {
2800       GLuint *depth = malloc(srcWidth * sizeof(GLuint));
2801       GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
2802
2803       if (!depth || !stencil) {
2804          free(depth);
2805          free(stencil);
2806          return GL_FALSE;
2807       }
2808
2809       /* In case we only upload depth we need to preserve the stencil */
2810       for (img = 0; img < srcDepth; img++) {
2811          GLuint *dstRow = (GLuint *) dstSlices[img];
2812          const GLubyte *src
2813             = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2814                   srcWidth, srcHeight,
2815                   srcFormat, srcType,
2816                   img, 0, 0);
2817          for (row = 0; row < srcHeight; row++) {
2818             GLint i;
2819             GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2820
2821             if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2822                keepstencil = GL_TRUE;
2823             }
2824             else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2825                keepdepth = GL_TRUE;
2826             }
2827
2828             if (keepdepth == GL_FALSE)
2829                /* the 24 depth bits will be in the low position: */
2830                _mesa_unpack_depth_span(ctx, srcWidth,
2831                                        GL_UNSIGNED_INT, /* dst type */
2832                                        keepstencil ? depth : dstRow, /* dst addr */
2833                                        depthScale,
2834                                        srcType, src, srcPacking);
2835
2836             if (keepstencil == GL_FALSE)
2837                /* get the 8-bit stencil values */
2838                _mesa_unpack_stencil_span(ctx, srcWidth,
2839                                          GL_UNSIGNED_BYTE, /* dst type */
2840                                          stencil, /* dst addr */
2841                                          srcType, src, srcPacking,
2842                                          ctx->_ImageTransferState);
2843
2844             for (i = 0; i < srcWidth; i++) {
2845                if (keepstencil)
2846                   dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2847                else
2848                   dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
2849             }
2850
2851             src += srcRowStride;
2852             dstRow += dstRowStride / sizeof(GLuint);
2853          }
2854       }
2855
2856       free(depth);
2857       free(stencil);
2858    }
2859    return GL_TRUE;
2860 }
2861
2862
2863 /**
2864  * Store a combined depth/stencil texture image.
2865  */
2866 static GLboolean
2867 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2868 {
2869    const GLuint depthScale = 0xffffff;
2870    const GLint srcRowStride
2871       = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2872    GLint img, row;
2873    GLuint *depth;
2874    GLubyte *stencil;
2875
2876    ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
2877    ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2878           srcFormat == GL_DEPTH_COMPONENT ||
2879           srcFormat == GL_STENCIL_INDEX);
2880    ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
2881           srcType == GL_UNSIGNED_INT_24_8_EXT);
2882
2883    depth = malloc(srcWidth * sizeof(GLuint));
2884    stencil = malloc(srcWidth * sizeof(GLubyte));
2885
2886    if (!depth || !stencil) {
2887       free(depth);
2888       free(stencil);
2889       return GL_FALSE;
2890    }
2891
2892    for (img = 0; img < srcDepth; img++) {
2893       GLuint *dstRow = (GLuint *) dstSlices[img];
2894       const GLubyte *src
2895          = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2896                                                 srcWidth, srcHeight,
2897                                                 srcFormat, srcType,
2898                                                 img, 0, 0);
2899       for (row = 0; row < srcHeight; row++) {
2900          GLint i;
2901          GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2902          
2903          if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2904             keepstencil = GL_TRUE;
2905          }
2906          else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2907             keepdepth = GL_TRUE;
2908          }
2909
2910          if (keepdepth == GL_FALSE)
2911             /* the 24 depth bits will be in the low position: */
2912             _mesa_unpack_depth_span(ctx, srcWidth,
2913                                     GL_UNSIGNED_INT, /* dst type */
2914                                     keepstencil ? depth : dstRow, /* dst addr */
2915                                     depthScale,
2916                                     srcType, src, srcPacking);   
2917
2918          if (keepstencil == GL_FALSE)
2919             /* get the 8-bit stencil values */
2920             _mesa_unpack_stencil_span(ctx, srcWidth,
2921                                       GL_UNSIGNED_BYTE, /* dst type */
2922                                       stencil, /* dst addr */
2923                                       srcType, src, srcPacking,
2924                                       ctx->_ImageTransferState);
2925
2926          /* merge stencil values into depth values */
2927          for (i = 0; i < srcWidth; i++) {
2928             if (keepstencil)
2929                dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2930             else
2931                dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
2932
2933          }
2934          src += srcRowStride;
2935          dstRow += dstRowStride / sizeof(GLuint);
2936       }
2937    }
2938
2939    free(depth);
2940    free(stencil);
2941
2942    return GL_TRUE;
2943 }
2944
2945
2946 /**
2947  * Store simple 8-bit/value stencil texture data.
2948  */
2949 static GLboolean
2950 _mesa_texstore_s8(TEXSTORE_PARAMS)
2951 {
2952    ASSERT(dstFormat == MESA_FORMAT_S8);
2953    ASSERT(srcFormat == GL_STENCIL_INDEX);
2954
2955    if (!ctx->_ImageTransferState &&
2956        !srcPacking->SwapBytes &&
2957        baseInternalFormat == srcFormat &&
2958        srcType == GL_UNSIGNED_BYTE) {
2959       /* simple memcpy path */
2960       memcpy_texture(ctx, dims,
2961                      dstFormat,
2962                      dstRowStride, dstSlices,
2963                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2964                      srcAddr, srcPacking);
2965    }
2966    else {
2967       const GLint srcRowStride
2968          = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2969       GLint img, row;
2970       GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
2971
2972       if (!stencil)
2973          return GL_FALSE;
2974
2975       for (img = 0; img < srcDepth; img++) {
2976          GLubyte *dstRow = dstSlices[img];
2977          const GLubyte *src
2978             = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2979                                                    srcWidth, srcHeight,
2980                                                    srcFormat, srcType,
2981                                                    img, 0, 0);
2982          for (row = 0; row < srcHeight; row++) {
2983             GLint i;
2984
2985             /* get the 8-bit stencil values */
2986             _mesa_unpack_stencil_span(ctx, srcWidth,
2987                                       GL_UNSIGNED_BYTE, /* dst type */
2988                                       stencil, /* dst addr */
2989                                       srcType, src, srcPacking,
2990                                       ctx->_ImageTransferState);
2991             /* merge stencil values into depth values */
2992             for (i = 0; i < srcWidth; i++)
2993                dstRow[i] = stencil[i];
2994
2995             src += srcRowStride;
2996             dstRow += dstRowStride / sizeof(GLubyte);
2997          }
2998       }
2999
3000       free(stencil);
3001    }
3002
3003    return GL_TRUE;
3004 }
3005
3006
3007 /**
3008  * Store an image in any of the formats:
3009  *   _mesa_texformat_rgba_float32
3010  *   _mesa_texformat_rgb_float32
3011  *   _mesa_texformat_alpha_float32
3012  *   _mesa_texformat_luminance_float32
3013  *   _mesa_texformat_luminance_alpha_float32
3014  *   _mesa_texformat_intensity_float32
3015  */
3016 static GLboolean
3017 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
3018 {
3019    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3020    const GLint components = _mesa_components_in_format(baseFormat);
3021
3022    ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
3023           dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
3024           dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
3025           dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
3026           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
3027           dstFormat == MESA_FORMAT_INTENSITY_FLOAT32 ||
3028           dstFormat == MESA_FORMAT_R_FLOAT32 ||
3029           dstFormat == MESA_FORMAT_RG_FLOAT32);
3030    ASSERT(baseInternalFormat == GL_RGBA ||
3031           baseInternalFormat == GL_RGB ||
3032           baseInternalFormat == GL_ALPHA ||
3033           baseInternalFormat == GL_LUMINANCE ||
3034           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3035           baseInternalFormat == GL_INTENSITY ||
3036           baseInternalFormat == GL_RED ||
3037           baseInternalFormat == GL_RG);
3038    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat));
3039
3040    if (!ctx->_ImageTransferState &&
3041        !srcPacking->SwapBytes &&
3042        baseInternalFormat == srcFormat &&
3043        baseInternalFormat == baseFormat &&
3044        srcType == GL_FLOAT) {
3045       /* simple memcpy path */
3046       memcpy_texture(ctx, dims,
3047                      dstFormat,
3048                      dstRowStride, dstSlices,
3049                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3050                      srcAddr, srcPacking);
3051    }
3052    else {
3053       /* general path */
3054       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3055                                                  baseInternalFormat,
3056                                                  baseFormat,
3057                                                  srcWidth, srcHeight, srcDepth,
3058                                                  srcFormat, srcType, srcAddr,
3059                                                  srcPacking,
3060                                                  ctx->_ImageTransferState);
3061       const GLfloat *srcRow = tempImage;
3062       GLint bytesPerRow;
3063       GLint img, row;
3064       if (!tempImage)
3065          return GL_FALSE;
3066       bytesPerRow = srcWidth * components * sizeof(GLfloat);
3067       for (img = 0; img < srcDepth; img++) {
3068          GLubyte *dstRow = dstSlices[img];
3069          for (row = 0; row < srcHeight; row++) {
3070             memcpy(dstRow, srcRow, bytesPerRow);
3071             dstRow += dstRowStride;
3072             srcRow += srcWidth * components;
3073          }
3074       }
3075
3076       free((void *) tempImage);
3077    }
3078    return GL_TRUE;
3079 }
3080
3081
3082
3083 /**
3084  * As above, but store 16-bit floats.
3085  */
3086 static GLboolean
3087 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
3088 {
3089    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3090    const GLint components = _mesa_components_in_format(baseFormat);
3091
3092    ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
3093           dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
3094           dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
3095           dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
3096           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
3097           dstFormat == MESA_FORMAT_INTENSITY_FLOAT16 ||
3098           dstFormat == MESA_FORMAT_R_FLOAT16 ||
3099           dstFormat == MESA_FORMAT_RG_FLOAT16);
3100    ASSERT(baseInternalFormat == GL_RGBA ||
3101           baseInternalFormat == GL_RGB ||
3102           baseInternalFormat == GL_ALPHA ||
3103           baseInternalFormat == GL_LUMINANCE ||
3104           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3105           baseInternalFormat == GL_INTENSITY ||
3106           baseInternalFormat == GL_RED ||
3107           baseInternalFormat == GL_RG);
3108    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB));
3109
3110    if (!ctx->_ImageTransferState &&
3111        !srcPacking->SwapBytes &&
3112        baseInternalFormat == srcFormat &&
3113        baseInternalFormat == baseFormat &&
3114        srcType == GL_HALF_FLOAT_ARB) {
3115       /* simple memcpy path */
3116       memcpy_texture(ctx, dims,
3117                      dstFormat,
3118                      dstRowStride, dstSlices,
3119                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3120                      srcAddr, srcPacking);
3121    }
3122    else {
3123       /* general path */
3124       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3125                                                  baseInternalFormat,
3126                                                  baseFormat,
3127                                                  srcWidth, srcHeight, srcDepth,
3128                                                  srcFormat, srcType, srcAddr,
3129                                                  srcPacking,
3130                                                  ctx->_ImageTransferState);
3131       const GLfloat *src = tempImage;
3132       GLint img, row;
3133       if (!tempImage)
3134          return GL_FALSE;
3135       for (img = 0; img < srcDepth; img++) {
3136          GLubyte *dstRow = dstSlices[img];
3137          for (row = 0; row < srcHeight; row++) {
3138             GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
3139             GLint i;
3140             for (i = 0; i < srcWidth * components; i++) {
3141                dstTexel[i] = _mesa_float_to_half(src[i]);
3142             }
3143             dstRow += dstRowStride;
3144             src += srcWidth * components;
3145          }
3146       }
3147
3148       free((void *) tempImage);
3149    }
3150    return GL_TRUE;
3151 }
3152
3153
3154 /* non-normalized, signed int8 */
3155 static GLboolean
3156 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
3157 {
3158    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3159    const GLint components = _mesa_components_in_format(baseFormat);
3160
3161    ASSERT(dstFormat == MESA_FORMAT_R_INT8 ||
3162           dstFormat == MESA_FORMAT_RG_INT8 ||
3163           dstFormat == MESA_FORMAT_RGB_INT8 ||
3164           dstFormat == MESA_FORMAT_RGBA_INT8 ||
3165           dstFormat == MESA_FORMAT_ALPHA_INT8 ||
3166           dstFormat == MESA_FORMAT_INTENSITY_INT8 ||
3167           dstFormat == MESA_FORMAT_LUMINANCE_INT8 ||
3168           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT8);
3169    ASSERT(baseInternalFormat == GL_RGBA ||
3170           baseInternalFormat == GL_RGB ||
3171           baseInternalFormat == GL_RG ||
3172           baseInternalFormat == GL_RED ||
3173           baseInternalFormat == GL_ALPHA ||
3174           baseInternalFormat == GL_LUMINANCE ||
3175           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3176           baseInternalFormat == GL_INTENSITY);
3177    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte));
3178
3179    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3180     * to integer formats.
3181     */
3182    if (!srcPacking->SwapBytes &&
3183        baseInternalFormat == srcFormat &&
3184        srcType == GL_BYTE) {
3185       /* simple memcpy path */
3186       memcpy_texture(ctx, dims,
3187                      dstFormat,
3188                      dstRowStride, dstSlices,
3189                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3190                      srcAddr, srcPacking);
3191    }
3192    else {
3193       /* general path */
3194       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3195                                                      baseInternalFormat,
3196                                                      baseFormat,
3197                                                      srcWidth, srcHeight, srcDepth,
3198                                                      srcFormat, srcType,
3199                                                      srcAddr,
3200                                                      srcPacking);
3201       const GLuint *src = tempImage;
3202       GLint img, row;
3203       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3204       if (!tempImage)
3205          return GL_FALSE;
3206       for (img = 0; img < srcDepth; img++) {
3207          GLubyte *dstRow = dstSlices[img];
3208          for (row = 0; row < srcHeight; row++) {
3209             GLbyte *dstTexel = (GLbyte *) dstRow;
3210             GLint i;
3211             if (is_unsigned) {
3212                for (i = 0; i < srcWidth * components; i++) {
3213                   dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
3214                }
3215             } else {
3216                for (i = 0; i < srcWidth * components; i++) {
3217                   dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
3218                }
3219             }
3220             dstRow += dstRowStride;
3221             src += srcWidth * components;
3222          }
3223       }
3224
3225       free((void *) tempImage);
3226    }
3227    return GL_TRUE;
3228 }
3229
3230
3231 /* non-normalized, signed int16 */
3232 static GLboolean
3233 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
3234 {
3235    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3236    const GLint components = _mesa_components_in_format(baseFormat);
3237
3238    ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
3239           dstFormat == MESA_FORMAT_RG_INT16 ||
3240           dstFormat == MESA_FORMAT_RGB_INT16 ||
3241           dstFormat == MESA_FORMAT_RGBA_INT16 ||
3242           dstFormat == MESA_FORMAT_ALPHA_INT16 ||
3243           dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
3244           dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
3245           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
3246    ASSERT(baseInternalFormat == GL_RGBA ||
3247           baseInternalFormat == GL_RGB ||
3248           baseInternalFormat == GL_RG ||
3249           baseInternalFormat == GL_RED ||
3250           baseInternalFormat == GL_ALPHA ||
3251           baseInternalFormat == GL_LUMINANCE ||
3252           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3253           baseInternalFormat == GL_INTENSITY);
3254    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort));
3255
3256    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3257     * to integer formats.
3258     */
3259    if (!srcPacking->SwapBytes &&
3260        baseInternalFormat == srcFormat &&
3261        srcType == GL_SHORT) {
3262       /* simple memcpy path */
3263       memcpy_texture(ctx, dims,
3264                      dstFormat,
3265                      dstRowStride, dstSlices,
3266                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3267                      srcAddr, srcPacking);
3268    }
3269    else {
3270       /* general path */
3271       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3272                                                      baseInternalFormat,
3273                                                      baseFormat,
3274                                                      srcWidth, srcHeight, srcDepth,
3275                                                      srcFormat, srcType,
3276                                                      srcAddr,
3277                                                      srcPacking);
3278       const GLuint *src = tempImage;
3279       GLint img, row;
3280       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3281       if (!tempImage)
3282          return GL_FALSE;
3283       for (img = 0; img < srcDepth; img++) {
3284          GLubyte *dstRow = dstSlices[img];
3285          for (row = 0; row < srcHeight; row++) {
3286             GLshort *dstTexel = (GLshort *) dstRow;
3287             GLint i;
3288             if (is_unsigned) {
3289                for (i = 0; i < srcWidth * components; i++) {
3290                   dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
3291                }
3292             } else {
3293                for (i = 0; i < srcWidth * components; i++) {
3294                   dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
3295                }
3296             }
3297             dstRow += dstRowStride;
3298             src += srcWidth * components;
3299          }
3300       }
3301
3302       free((void *) tempImage);
3303    }
3304    return GL_TRUE;
3305 }
3306
3307
3308 /* non-normalized, signed int32 */
3309 static GLboolean
3310 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
3311 {
3312    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3313    const GLint components = _mesa_components_in_format(baseFormat);
3314
3315    ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
3316           dstFormat == MESA_FORMAT_RG_INT32 ||
3317           dstFormat == MESA_FORMAT_RGB_INT32 ||
3318           dstFormat == MESA_FORMAT_RGBA_INT32 ||
3319           dstFormat == MESA_FORMAT_ALPHA_INT32 ||
3320           dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
3321           dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
3322           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
3323    ASSERT(baseInternalFormat == GL_RGBA ||
3324           baseInternalFormat == GL_RGB ||
3325           baseInternalFormat == GL_RG ||
3326           baseInternalFormat == GL_RED ||
3327           baseInternalFormat == GL_ALPHA ||
3328           baseInternalFormat == GL_LUMINANCE ||
3329           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3330           baseInternalFormat == GL_INTENSITY);
3331    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint));
3332
3333    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3334     * to integer formats.
3335     */
3336    if (!srcPacking->SwapBytes &&
3337        baseInternalFormat == srcFormat &&
3338        srcType == GL_INT) {
3339       /* simple memcpy path */
3340       memcpy_texture(ctx, dims,
3341                      dstFormat,
3342                      dstRowStride, dstSlices,
3343                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3344                      srcAddr, srcPacking);
3345    }
3346    else {
3347       /* general path */
3348       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3349                                                      baseInternalFormat,
3350                                                      baseFormat,
3351                                                      srcWidth, srcHeight, srcDepth,
3352                                                      srcFormat, srcType,
3353                                                      srcAddr,
3354                                                      srcPacking);
3355       const GLuint *src = tempImage;
3356       GLint img, row;
3357       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3358       if (!tempImage)
3359          return GL_FALSE;
3360       for (img = 0; img < srcDepth; img++) {
3361          GLubyte *dstRow = dstSlices[img];
3362          for (row = 0; row < srcHeight; row++) {
3363             GLint *dstTexel = (GLint *) dstRow;
3364             GLint i;
3365             if (is_unsigned) {
3366                for (i = 0; i < srcWidth * components; i++) {
3367                   dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
3368                }
3369             } else {
3370                for (i = 0; i < srcWidth * components; i++) {
3371                   dstTexel[i] = (GLint) src[i];
3372                }
3373             }
3374             dstRow += dstRowStride;
3375             src += srcWidth * components;
3376          }
3377       }
3378
3379       free((void *) tempImage);
3380    }
3381    return GL_TRUE;
3382 }
3383
3384
3385 /* non-normalized, unsigned int8 */
3386 static GLboolean
3387 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3388 {
3389    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3390    const GLint components = _mesa_components_in_format(baseFormat);
3391
3392    ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
3393           dstFormat == MESA_FORMAT_RG_UINT8 ||
3394           dstFormat == MESA_FORMAT_RGB_UINT8 ||
3395           dstFormat == MESA_FORMAT_RGBA_UINT8 ||
3396           dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
3397           dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
3398           dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
3399           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
3400    ASSERT(baseInternalFormat == GL_RGBA ||
3401           baseInternalFormat == GL_RGB ||
3402           baseInternalFormat == GL_RG ||
3403           baseInternalFormat == GL_RED ||
3404           baseInternalFormat == GL_ALPHA ||
3405           baseInternalFormat == GL_LUMINANCE ||
3406           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3407           baseInternalFormat == GL_INTENSITY);
3408    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte));
3409
3410    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3411     * to integer formats.
3412     */
3413    if (!srcPacking->SwapBytes &&
3414        baseInternalFormat == srcFormat &&
3415        srcType == GL_UNSIGNED_BYTE) {
3416       /* simple memcpy path */
3417       memcpy_texture(ctx, dims,
3418                      dstFormat,
3419                      dstRowStride, dstSlices,
3420                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3421                      srcAddr, srcPacking);
3422    }
3423    else {
3424       /* general path */
3425       const GLuint *tempImage =
3426          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3427                               srcWidth, srcHeight, srcDepth,
3428                               srcFormat, srcType, srcAddr, srcPacking);
3429       const GLuint *src = tempImage;
3430       GLint img, row;
3431       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3432       if (!tempImage)
3433          return GL_FALSE;
3434       for (img = 0; img < srcDepth; img++) {
3435          GLubyte *dstRow = dstSlices[img];
3436          for (row = 0; row < srcHeight; row++) {
3437             GLubyte *dstTexel = (GLubyte *) dstRow;
3438             GLint i;
3439             if (is_unsigned) {
3440                for (i = 0; i < srcWidth * components; i++) {
3441                   dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
3442                }
3443             } else {
3444                for (i = 0; i < srcWidth * components; i++) {
3445                   dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
3446                }
3447             }
3448             dstRow += dstRowStride;
3449             src += srcWidth * components;
3450          }
3451       }
3452
3453       free((void *) tempImage);
3454    }
3455    return GL_TRUE;
3456 }
3457
3458
3459 /* non-normalized, unsigned int16 */
3460 static GLboolean
3461 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3462 {
3463    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3464    const GLint components = _mesa_components_in_format(baseFormat);
3465
3466    ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
3467           dstFormat == MESA_FORMAT_RG_UINT16 ||
3468           dstFormat == MESA_FORMAT_RGB_UINT16 ||
3469           dstFormat == MESA_FORMAT_RGBA_UINT16 ||
3470           dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
3471           dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
3472           dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
3473           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
3474    ASSERT(baseInternalFormat == GL_RGBA ||
3475           baseInternalFormat == GL_RGB ||
3476           baseInternalFormat == GL_RG ||
3477           baseInternalFormat == GL_RED ||
3478           baseInternalFormat == GL_ALPHA ||
3479           baseInternalFormat == GL_LUMINANCE ||
3480           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3481           baseInternalFormat == GL_INTENSITY);
3482    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort));
3483
3484    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3485     * to integer formats.
3486     */
3487    if (!srcPacking->SwapBytes &&
3488        baseInternalFormat == srcFormat &&
3489        srcType == GL_UNSIGNED_SHORT) {
3490       /* simple memcpy path */
3491       memcpy_texture(ctx, dims,
3492                      dstFormat,
3493                      dstRowStride, dstSlices,
3494                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3495                      srcAddr, srcPacking);
3496    }
3497    else {
3498       /* general path */
3499       const GLuint *tempImage =
3500          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3501                               srcWidth, srcHeight, srcDepth,
3502                               srcFormat, srcType, srcAddr, srcPacking);
3503       const GLuint *src = tempImage;
3504       GLint img, row;
3505       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3506       if (!tempImage)
3507          return GL_FALSE;
3508       for (img = 0; img < srcDepth; img++) {
3509          GLubyte *dstRow = dstSlices[img];
3510          for (row = 0; row < srcHeight; row++) {
3511             GLushort *dstTexel = (GLushort *) dstRow;
3512             GLint i;
3513             if (is_unsigned) {
3514                for (i = 0; i < srcWidth * components; i++) {
3515                   dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
3516               }
3517             } else {
3518                for (i = 0; i < srcWidth * components; i++) {
3519                   dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
3520                }
3521             }
3522             dstRow += dstRowStride;
3523             src += srcWidth * components;
3524          }
3525       }
3526
3527       free((void *) tempImage);
3528    }
3529    return GL_TRUE;
3530 }
3531
3532
3533 /* non-normalized, unsigned int32 */
3534 static GLboolean
3535 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3536 {
3537    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3538    const GLint components = _mesa_components_in_format(baseFormat);
3539
3540    ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
3541           dstFormat == MESA_FORMAT_RG_UINT32 ||
3542           dstFormat == MESA_FORMAT_RGB_UINT32 ||
3543           dstFormat == MESA_FORMAT_RGBA_UINT32 ||
3544           dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
3545           dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
3546           dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
3547           dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
3548    ASSERT(baseInternalFormat == GL_RGBA ||
3549           baseInternalFormat == GL_RGB ||
3550           baseInternalFormat == GL_RG ||
3551           baseInternalFormat == GL_RED ||
3552           baseInternalFormat == GL_ALPHA ||
3553           baseInternalFormat == GL_LUMINANCE ||
3554           baseInternalFormat == GL_LUMINANCE_ALPHA ||
3555           baseInternalFormat == GL_INTENSITY);
3556    ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint));
3557
3558    /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3559     * to integer formats.
3560     */
3561    if (!srcPacking->SwapBytes &&
3562        baseInternalFormat == srcFormat &&
3563        srcType == GL_UNSIGNED_INT) {
3564       /* simple memcpy path */
3565       memcpy_texture(ctx, dims,
3566                      dstFormat,
3567                      dstRowStride, dstSlices,
3568                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3569                      srcAddr, srcPacking);
3570    }
3571    else {
3572       /* general path */
3573       const GLuint *tempImage =
3574          make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3575                               srcWidth, srcHeight, srcDepth,
3576                               srcFormat, srcType, srcAddr, srcPacking);
3577       const GLuint *src = tempImage;
3578       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3579       GLint img, row;
3580       if (!tempImage)
3581          return GL_FALSE;
3582       for (img = 0; img < srcDepth; img++) {
3583          GLubyte *dstRow = dstSlices[img];
3584          for (row = 0; row < srcHeight; row++) {
3585             GLuint *dstTexel = (GLuint *) dstRow;
3586             GLint i;
3587             if (is_unsigned) {
3588                for (i = 0; i < srcWidth * components; i++) {
3589                   dstTexel[i] = src[i];
3590                }
3591             } else {
3592                for (i = 0; i < srcWidth * components; i++) {
3593                   dstTexel[i] = MAX2((GLint) src[i], 0);
3594                }
3595             }
3596             dstRow += dstRowStride;
3597             src += srcWidth * components;
3598          }
3599       }
3600
3601       free((void *) tempImage);
3602    }
3603    return GL_TRUE;
3604 }
3605
3606
3607 static GLboolean
3608 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3609 {
3610    gl_format newDstFormat;
3611    GLboolean k;
3612
3613    ASSERT(dstFormat == MESA_FORMAT_SRGB8);
3614
3615    /* reuse normal rgb texstore code */
3616    newDstFormat = MESA_FORMAT_RGB888;
3617
3618    k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3619                              newDstFormat,
3620                              dstRowStride, dstSlices,
3621                              srcWidth, srcHeight, srcDepth,
3622                              srcFormat, srcType,
3623                              srcAddr, srcPacking);
3624    return k;
3625 }
3626
3627
3628 static GLboolean
3629 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
3630 {
3631    gl_format newDstFormat;
3632    GLboolean k;
3633
3634    ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
3635
3636    /* reuse normal rgba texstore code */
3637    newDstFormat = MESA_FORMAT_RGBA8888;
3638    k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
3639                                newDstFormat,
3640                                dstRowStride, dstSlices,
3641                                srcWidth, srcHeight, srcDepth,
3642                                srcFormat, srcType,
3643                                srcAddr, srcPacking);
3644    return k;
3645 }
3646
3647
3648 static GLboolean
3649 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
3650 {
3651    gl_format newDstFormat;
3652    GLboolean k;
3653
3654    ASSERT(dstFormat == MESA_FORMAT_SARGB8);
3655
3656    /* reuse normal rgba texstore code */
3657    newDstFormat = MESA_FORMAT_ARGB8888;
3658
3659    k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
3660                                newDstFormat,
3661                                dstRowStride, dstSlices,
3662                                srcWidth, srcHeight, srcDepth,
3663                                srcFormat, srcType,
3664                                srcAddr, srcPacking);
3665    return k;
3666 }
3667
3668
3669 static GLboolean
3670 _mesa_texstore_sl8(TEXSTORE_PARAMS)
3671 {
3672    gl_format newDstFormat;
3673    GLboolean k;
3674
3675    ASSERT(dstFormat == MESA_FORMAT_SL8);
3676
3677    newDstFormat = MESA_FORMAT_L8;
3678
3679    /* _mesa_textore_a8 handles luminance8 too */
3680    k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
3681                              newDstFormat,
3682                              dstRowStride, dstSlices,
3683                              srcWidth, srcHeight, srcDepth,
3684                              srcFormat, srcType,
3685                              srcAddr, srcPacking);
3686    return k;
3687 }
3688
3689
3690 static GLboolean
3691 _mesa_texstore_sla8(TEXSTORE_PARAMS)
3692 {
3693    gl_format newDstFormat;
3694    GLboolean k;
3695
3696    ASSERT(dstFormat == MESA_FORMAT_SLA8);
3697
3698    /* reuse normal luminance/alpha texstore code */
3699    newDstFormat = MESA_FORMAT_AL88;
3700
3701    k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
3702                               newDstFormat,
3703                               dstRowStride, dstSlices,
3704                               srcWidth, srcHeight, srcDepth,
3705                               srcFormat, srcType,
3706                               srcAddr, srcPacking);
3707    return k;
3708 }
3709
3710 static GLboolean
3711 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
3712 {
3713    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3714
3715    ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
3716    ASSERT(baseInternalFormat == GL_RGB);
3717
3718    if (!ctx->_ImageTransferState &&
3719        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3720                                             srcPacking->SwapBytes)) {
3721       /* simple memcpy path */
3722       memcpy_texture(ctx, dims,
3723                      dstFormat,
3724                      dstRowStride, dstSlices,
3725                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3726                      srcAddr, srcPacking);
3727    }
3728    else {
3729       /* general path */
3730       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3731                                                  baseInternalFormat,
3732                                                  baseFormat,
3733                                                  srcWidth, srcHeight, srcDepth,
3734                                                  srcFormat, srcType, srcAddr,
3735                                                  srcPacking,
3736                                                  ctx->_ImageTransferState);
3737       const GLfloat *srcRow = tempImage;
3738       GLint img, row, col;
3739       if (!tempImage)
3740          return GL_FALSE;
3741       for (img = 0; img < srcDepth; img++) {
3742          GLubyte *dstRow = dstSlices[img];
3743          for (row = 0; row < srcHeight; row++) {
3744             GLuint *dstUI = (GLuint*)dstRow;
3745             for (col = 0; col < srcWidth; col++) {
3746                dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
3747             }
3748             dstRow += dstRowStride;
3749             srcRow += srcWidth * 3;
3750          }
3751       }
3752
3753       free((void *) tempImage);
3754    }
3755    return GL_TRUE;
3756 }
3757
3758 static GLboolean
3759 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
3760 {
3761    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3762
3763    ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
3764    ASSERT(baseInternalFormat == GL_RGB);
3765
3766    if (!ctx->_ImageTransferState &&
3767        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3768                                             srcPacking->SwapBytes)) {
3769       /* simple memcpy path */
3770       memcpy_texture(ctx, dims,
3771                      dstFormat,
3772                      dstRowStride, dstSlices,
3773                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3774                      srcAddr, srcPacking);
3775    }
3776    else {
3777       /* general path */
3778       const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3779                                                  baseInternalFormat,
3780                                                  baseFormat,
3781                                                  srcWidth, srcHeight, srcDepth,
3782                                                  srcFormat, srcType, srcAddr,
3783                                                  srcPacking,
3784                                                  ctx->_ImageTransferState);
3785       const GLfloat *srcRow = tempImage;
3786       GLint img, row, col;
3787       if (!tempImage)
3788          return GL_FALSE;
3789       for (img = 0; img < srcDepth; img++) {
3790          GLubyte *dstRow = dstSlices[img];
3791          for (row = 0; row < srcHeight; row++) {
3792             GLuint *dstUI = (GLuint*)dstRow;
3793             for (col = 0; col < srcWidth; col++) {
3794                dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
3795             }
3796             dstRow += dstRowStride;
3797             srcRow += srcWidth * 3;
3798          }
3799       }
3800
3801       free((void *) tempImage);
3802    }
3803    return GL_TRUE;
3804 }
3805
3806
3807 static GLboolean
3808 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
3809 {
3810    ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
3811    ASSERT(srcFormat == GL_DEPTH_STENCIL ||
3812           srcFormat == GL_DEPTH_COMPONENT ||
3813           srcFormat == GL_STENCIL_INDEX);
3814    ASSERT(srcFormat != GL_DEPTH_STENCIL ||
3815           srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
3816
3817    if (srcFormat == GL_DEPTH_STENCIL &&
3818        ctx->Pixel.DepthScale == 1.0f &&
3819        ctx->Pixel.DepthBias == 0.0f &&
3820        !srcPacking->SwapBytes) {
3821       /* simple path */
3822       memcpy_texture(ctx, dims,
3823                      dstFormat,
3824                      dstRowStride, dstSlices,
3825                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3826                      srcAddr, srcPacking);
3827    }
3828    else if (srcFormat == GL_DEPTH_COMPONENT ||
3829             srcFormat == GL_STENCIL_INDEX) {
3830       GLint img, row;
3831       const GLint srcRowStride
3832          = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3833          / sizeof(uint64_t);
3834
3835       /* In case we only upload depth we need to preserve the stencil */
3836       for (img = 0; img < srcDepth; img++) {
3837          uint64_t *dstRow = (uint64_t *) dstSlices[img];
3838          const uint64_t *src
3839             = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
3840                   srcWidth, srcHeight,
3841                   srcFormat, srcType,
3842                   img, 0, 0);
3843          for (row = 0; row < srcHeight; row++) {
3844             /* The unpack functions with:
3845              *    dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
3846              * only write their own dword, so the other dword (stencil
3847              * or depth) is preserved. */
3848             if (srcFormat != GL_STENCIL_INDEX)
3849                _mesa_unpack_depth_span(ctx, srcWidth,
3850                                        GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3851                                        dstRow, /* dst addr */
3852                                        ~0U, srcType, src, srcPacking);
3853
3854             if (srcFormat != GL_DEPTH_COMPONENT)
3855                _mesa_unpack_stencil_span(ctx, srcWidth,
3856                                          GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3857                                          dstRow, /* dst addr */
3858                                          srcType, src, srcPacking,
3859                                          ctx->_ImageTransferState);
3860
3861             src += srcRowStride;
3862             dstRow += dstRowStride / sizeof(uint64_t);
3863          }
3864       }
3865    }
3866    return GL_TRUE;
3867 }
3868
3869 static GLboolean
3870 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
3871 {
3872    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3873
3874    ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
3875    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3876
3877    if (baseInternalFormat == GL_RGBA &&
3878        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3879                                             srcPacking->SwapBytes)) {
3880       /* simple memcpy path */
3881       memcpy_texture(ctx, dims,
3882                      dstFormat,
3883                      dstRowStride, dstSlices,
3884                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3885                      srcAddr, srcPacking);
3886    }
3887    else {
3888       /* general path */
3889       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3890                                                      baseInternalFormat,
3891                                                      baseFormat,
3892                                                      srcWidth, srcHeight,
3893                                                      srcDepth, srcFormat,
3894                                                      srcType, srcAddr,
3895                                                      srcPacking);
3896       const GLuint *src = tempImage;
3897       GLint img, row, col;
3898       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3899       if (!tempImage)
3900          return GL_FALSE;
3901       for (img = 0; img < srcDepth; img++) {
3902          GLubyte *dstRow = dstSlices[img];
3903
3904          for (row = 0; row < srcHeight; row++) {
3905             GLuint *dstUI = (GLuint *) dstRow;
3906             if (is_unsigned) {
3907                for (col = 0; col < srcWidth; col++) {
3908                   GLushort a,r,g,b;
3909                   r = MIN2(src[RCOMP], 0x3ff);
3910                   g = MIN2(src[GCOMP], 0x3ff);
3911                   b = MIN2(src[BCOMP], 0x3ff);
3912                   a = MIN2(src[ACOMP], 0x003);
3913                   dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3914                   src += 4;
3915                }
3916             } else {
3917                for (col = 0; col < srcWidth; col++) {
3918                   GLushort a,r,g,b;
3919                   r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
3920                   g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
3921                   b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
3922                   a = CLAMP((GLint) src[ACOMP], 0, 0x003);
3923                   dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3924                   src += 4;
3925                }
3926             }
3927             dstRow += dstRowStride;
3928          }
3929       }
3930       free((void *) tempImage);
3931    }
3932    return GL_TRUE;
3933 }
3934
3935 static GLboolean
3936 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
3937 {
3938    const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3939
3940    ASSERT(dstFormat == MESA_FORMAT_ABGR2101010_UINT);
3941    ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3942
3943    if (baseInternalFormat == GL_RGBA &&
3944        _mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3945                                             srcPacking->SwapBytes)) {
3946       /* simple memcpy path */
3947       memcpy_texture(ctx, dims,
3948                      dstFormat,
3949                      dstRowStride, dstSlices,
3950                      srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3951                      srcAddr, srcPacking);
3952    }
3953    else {
3954       /* general path */
3955       const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3956                                                      baseInternalFormat,
3957                                                      baseFormat,
3958                                                      srcWidth, srcHeight,
3959                                                      srcDepth, srcFormat,
3960                                                      srcType, srcAddr,
3961                                                      srcPacking);
3962       const GLuint *src = tempImage;
3963       GLint img, row, col;
3964       GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3965       if (!tempImage)
3966          return GL_FALSE;
3967       for (img = 0; img < srcDepth; img++) {
3968          GLubyte *dstRow = dstSlices[img];
3969
3970          for (row = 0; row < srcHeight; row++) {
3971             GLuint *dstUI = (GLuint *) dstRow;
3972             if (is_unsigned) {
3973                for (col = 0; col < srcWidth; col++) {
3974                   GLushort a,r,g,b;
3975                   r = MIN2(src[RCOMP], 0x3ff);
3976                   g = MIN2(src[GCOMP], 0x3ff);
3977                   b = MIN2(src[BCOMP], 0x3ff);
3978                   a = MIN2(src[ACOMP], 0x003);
3979                   dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
3980                   src += 4;
3981                }
3982             } else {
3983                for (col = 0; col < srcWidth; col++) {
3984                   GLushort a,r,g,b;
3985                   r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
3986                   g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
3987                   b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
3988                   a = CLAMP((GLint) src[ACOMP], 0, 0x003);
3989                   dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
3990                   src += 4;
3991                }
3992             }
3993             dstRow += dstRowStride;
3994          }
3995       }
3996       free((void *) tempImage);
3997    }
3998    return GL_TRUE;
3999 }
4000
4001 static GLboolean
4002 _mesa_texstore_null(TEXSTORE_PARAMS)
4003 {
4004    (void) ctx; (void) dims;
4005    (void) baseInternalFormat;
4006    (void) dstFormat;
4007    (void) dstRowStride; (void) dstSlices,
4008    (void) srcWidth; (void) srcHeight; (void) srcDepth;
4009    (void) srcFormat; (void) srcType;
4010    (void) srcAddr;
4011    (void) srcPacking;
4012
4013    /* should never happen */
4014    _mesa_problem(NULL, "_mesa_texstore_null() is called");
4015    return GL_FALSE;
4016 }
4017
4018
4019 /**
4020  * Return the StoreTexImageFunc pointer to store an image in the given format.
4021  */
4022 static StoreTexImageFunc
4023 _mesa_get_texstore_func(gl_format format)
4024 {
4025    static StoreTexImageFunc table[MESA_FORMAT_COUNT];
4026    static GLboolean initialized = GL_FALSE;
4027
4028    if (!initialized) {
4029       table[MESA_FORMAT_NONE] = _mesa_texstore_null;
4030
4031       table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
4032       table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
4033       table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
4034       table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
4035       table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
4036       table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
4037       table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
4038       table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
4039       table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
4040       table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
4041       table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
4042       table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
4043       table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
4044       table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
4045       table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
4046       table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
4047       table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
4048       table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
4049       table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
4050       table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
4051       table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
4052       table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
4053       table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
4054       table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
4055       table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
4056       table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
4057       table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
4058       table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
4059       table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
4060       table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
4061       table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
4062       table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
4063       table[MESA_FORMAT_GR88] = _mesa_texstore_unorm88;
4064       table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
4065       table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
4066       table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
4067       table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
4068       table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
4069       table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
4070       table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
4071       table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
4072       table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
4073       table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
4074       table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
4075       table[MESA_FORMAT_S8] = _mesa_texstore_s8;
4076       table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
4077       table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
4078       table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
4079       table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
4080       table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
4081       table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
4082       table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4083       table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4084       table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4085       table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
4086       table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
4087       table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
4088       table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4089       table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4090       table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4091       table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
4092       table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
4093       table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
4094       table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
4095       table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4096       table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4097       table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
4098       table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
4099       table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4100       table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4101       table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
4102       table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
4103       table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
4104       table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
4105       table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
4106       table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
4107       table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
4108       table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
4109       table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
4110       table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
4111       table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
4112       table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
4113       table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
4114       table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
4115       table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
4116       table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
4117       table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
4118       table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
4119       table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
4120       table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
4121       table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
4122       table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
4123       table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
4124       table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
4125       table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
4126       table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
4127       table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
4128       /* table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8; -- not implemented yet */
4129       /* table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac; -- not implemented yet */
4130       /* table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac; -- not implemented yet */
4131       /* table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac; -- not implemented yet */
4132       /* table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac; -- not implemented yet */
4133       /* table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac; -- not implemented yet */
4134       /* table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac; -- not implemented yet */
4135       /* table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
4136          _mesa_texstore_etc2_rgb8_punchthrough_alpha1; -- not implemented yet */
4137       /* table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
4138          _mesa_texstore_etc2_srgb8_punchthrough_alpha1; -- not implemented yet */
4139       table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
4140       table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
4141       table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
4142       table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
4143       table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
4144       table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
4145       table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
4146       table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
4147       table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
4148       table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
4149       table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
4150       table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
4151
4152       table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4153       table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4154       table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4155       table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4156       table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4157       table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4158
4159       table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
4160       table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
4161       table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
4162       table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
4163       table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
4164       table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
4165
4166       table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
4167       table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
4168       table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
4169       table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
4170       table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
4171       table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
4172
4173       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4174       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4175       table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4176       table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4177       table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4178       table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4179
4180       table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
4181       table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
4182       table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
4183       table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
4184       table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
4185       table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
4186       table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
4187       table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
4188       table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
4189       table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
4190       table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
4191       table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
4192
4193       table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
4194       table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
4195       table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
4196       table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
4197       table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
4198       table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
4199       table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
4200       table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
4201       table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
4202       table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
4203       table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
4204       table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
4205
4206       table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
4207       table[MESA_FORMAT_ABGR2101010_UINT] = _mesa_texstore_abgr2101010_uint;
4208       initialized = GL_TRUE;
4209    }
4210
4211    ASSERT(table[format]);
4212    return table[format];
4213 }
4214
4215
4216 /**
4217  * Store user data into texture memory.
4218  * Called via glTex[Sub]Image1/2/3D()
4219  */
4220 GLboolean
4221 _mesa_texstore(TEXSTORE_PARAMS)
4222 {
4223    StoreTexImageFunc storeImage;
4224    GLboolean success;
4225
4226    storeImage = _mesa_get_texstore_func(dstFormat);
4227
4228    success = storeImage(ctx, dims, baseInternalFormat,
4229                         dstFormat,
4230                         dstRowStride, dstSlices,
4231                         srcWidth, srcHeight, srcDepth,
4232                         srcFormat, srcType, srcAddr, srcPacking);
4233    return success;
4234 }
4235
4236
4237 /**
4238  * Normally, we'll only _write_ texel data to a texture when we map it.
4239  * But if the user is providing depth or stencil values and the texture
4240  * image is a combined depth/stencil format, we'll actually read from
4241  * the texture buffer too (in order to insert the depth or stencil values.
4242  * \param userFormat  the user-provided image format
4243  * \param texFormat  the destination texture format
4244  */
4245 static GLbitfield
4246 get_read_write_mode(GLenum userFormat, gl_format texFormat)
4247 {
4248    if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
4249        && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
4250       return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
4251    else
4252       return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
4253 }
4254
4255
4256 /**
4257  * Helper function for storing 1D, 2D, 3D whole and subimages into texture
4258  * memory.
4259  * The source of the image data may be user memory or a PBO.  In the later
4260  * case, we'll map the PBO, copy from it, then unmap it.
4261  */
4262 static void
4263 store_texsubimage(struct gl_context *ctx,
4264                   struct gl_texture_image *texImage,
4265                   GLint xoffset, GLint yoffset, GLint zoffset,
4266                   GLint width, GLint height, GLint depth,
4267                   GLenum format, GLenum type, const GLvoid *pixels,
4268                   const struct gl_pixelstore_attrib *packing,
4269                   const char *caller)
4270
4271 {
4272    const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
4273    const GLenum target = texImage->TexObject->Target;
4274    GLboolean success = GL_FALSE;
4275    GLuint dims, slice, numSlices = 1, sliceOffset = 0;
4276    GLint srcImageStride = 0;
4277    const GLubyte *src;
4278
4279    assert(xoffset + width <= texImage->Width);
4280    assert(yoffset + height <= texImage->Height);
4281    assert(zoffset + depth <= texImage->Depth);
4282
4283    switch (target) {
4284    case GL_TEXTURE_1D:
4285       dims = 1;
4286       break;
4287    case GL_TEXTURE_2D_ARRAY:
4288    case GL_TEXTURE_CUBE_MAP_ARRAY:
4289    case GL_TEXTURE_3D:
4290       dims = 3;
4291       break;
4292    default:
4293       dims = 2;
4294    }
4295
4296    /* get pointer to src pixels (may be in a pbo which we'll map here) */
4297    src = (const GLubyte *)
4298       _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
4299                                   format, type, pixels, packing, caller);
4300    if (!src)
4301       return;
4302
4303    /* compute slice info (and do some sanity checks) */
4304    switch (target) {
4305    case GL_TEXTURE_2D:
4306    case GL_TEXTURE_RECTANGLE:
4307    case GL_TEXTURE_CUBE_MAP:
4308       /* one image slice, nothing special needs to be done */
4309       break;
4310    case GL_TEXTURE_1D:
4311       assert(height == 1);
4312       assert(depth == 1);
4313       assert(yoffset == 0);
4314       assert(zoffset == 0);
4315       break;
4316    case GL_TEXTURE_1D_ARRAY:
4317       assert(depth == 1);
4318       assert(zoffset == 0);
4319       numSlices = height;
4320       sliceOffset = yoffset;
4321       height = 1;
4322       yoffset = 0;
4323       srcImageStride = _mesa_image_row_stride(packing, width, format, type);
4324       break;
4325    case GL_TEXTURE_2D_ARRAY:
4326       numSlices = depth;
4327       sliceOffset = zoffset;
4328       depth = 1;
4329       zoffset = 0;
4330       srcImageStride = _mesa_image_image_stride(packing, width, height,
4331                                                 format, type);
4332       break;
4333    case GL_TEXTURE_3D:
4334       /* we'll store 3D images as a series of slices */
4335       numSlices = depth;
4336       sliceOffset = zoffset;
4337       srcImageStride = _mesa_image_image_stride(packing, width, height,
4338                                                 format, type);
4339       break;
4340    case GL_TEXTURE_CUBE_MAP_ARRAY:
4341       numSlices = depth;
4342       sliceOffset = zoffset;
4343       srcImageStride = _mesa_image_image_stride(packing, width, height,
4344                                                 format, type);
4345       break;
4346    default:
4347       _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
4348       return;
4349    }
4350
4351    assert(numSlices == 1 || srcImageStride != 0);
4352
4353    for (slice = 0; slice < numSlices; slice++) {
4354       GLubyte *dstMap;
4355       GLint dstRowStride;
4356
4357       ctx->Driver.MapTextureImage(ctx, texImage,
4358                                   slice + sliceOffset,
4359                                   xoffset, yoffset, width, height,
4360                                   mapMode, &dstMap, &dstRowStride);
4361       if (dstMap) {
4362          /* Note: we're only storing a 2D (or 1D) slice at a time but we need
4363           * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
4364           * used for 3D images.
4365           */
4366          success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
4367                                   texImage->TexFormat,
4368                                   dstRowStride,
4369                                   &dstMap,
4370                                   width, height, 1,  /* w, h, d */
4371                                   format, type, src, packing);
4372
4373          ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
4374       }
4375
4376       src += srcImageStride;
4377
4378       if (!success)
4379          break;
4380    }
4381
4382    if (!success)
4383       _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
4384
4385    _mesa_unmap_teximage_pbo(ctx, packing);
4386 }
4387
4388
4389
4390 /**
4391  * Fallback code for ctx->Driver.TexImage().
4392  * Basically, allocate storage for the texture image, then copy the
4393  * user's image into it.
4394  */
4395 void
4396 _mesa_store_teximage(struct gl_context *ctx,
4397                      GLuint dims,
4398                      struct gl_texture_image *texImage,
4399                      GLenum format, GLenum type, const GLvoid *pixels,
4400                      const struct gl_pixelstore_attrib *packing)
4401 {
4402    assert(dims == 1 || dims == 2 || dims == 3);
4403
4404    if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
4405       return;
4406
4407    /* allocate storage for texture data */
4408    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4409       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
4410       return;
4411    }
4412
4413    store_texsubimage(ctx, texImage,
4414                      0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
4415                      format, type, pixels, packing, "glTexImage");
4416 }
4417
4418
4419 /*
4420  * Fallback for Driver.TexSubImage().
4421  */
4422 void
4423 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
4424                         struct gl_texture_image *texImage,
4425                         GLint xoffset, GLint yoffset, GLint zoffset,
4426                         GLint width, GLint height, GLint depth,
4427                         GLenum format, GLenum type, const void *pixels,
4428                         const struct gl_pixelstore_attrib *packing)
4429 {
4430    store_texsubimage(ctx, texImage,
4431                      xoffset, yoffset, zoffset, width, height, depth,
4432                      format, type, pixels, packing, "glTexSubImage");
4433 }
4434
4435
4436 /**
4437  * Fallback for Driver.CompressedTexImage()
4438  */
4439 void
4440 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
4441                                 struct gl_texture_image *texImage,
4442                                 GLsizei imageSize, const GLvoid *data)
4443 {
4444    /* only 2D compressed images are supported at this time */
4445    if (dims != 2) {
4446       _mesa_problem(ctx, "Unexpected glCompressedTexImage1D/3D call");
4447       return;
4448    }
4449
4450    /* This is pretty simple, because unlike the general texstore path we don't
4451     * have to worry about the usual image unpacking or image transfer
4452     * operations.
4453     */
4454    ASSERT(texImage);
4455    ASSERT(texImage->Width > 0);
4456    ASSERT(texImage->Height > 0);
4457    ASSERT(texImage->Depth == 1);
4458
4459    /* allocate storage for texture data */
4460    if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4461       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
4462       return;
4463    }
4464
4465    _mesa_store_compressed_texsubimage(ctx, dims, texImage,
4466                                       0, 0, 0,
4467                                       texImage->Width, texImage->Height, texImage->Depth,
4468                                       texImage->TexFormat,
4469                                       imageSize, data);
4470 }
4471
4472
4473 /**
4474  * Fallback for Driver.CompressedTexSubImage()
4475  */
4476 void
4477 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
4478                                    struct gl_texture_image *texImage,
4479                                    GLint xoffset, GLint yoffset, GLint zoffset,
4480                                    GLsizei width, GLsizei height, GLsizei depth,
4481                                    GLenum format,
4482                                    GLsizei imageSize, const GLvoid *data)
4483 {
4484    GLint bytesPerRow, dstRowStride, srcRowStride;
4485    GLint i, rows;
4486    GLubyte *dstMap;
4487    const GLubyte *src;
4488    const gl_format texFormat = texImage->TexFormat;
4489    GLuint bw, bh;
4490
4491    if (dims != 2) {
4492       _mesa_problem(ctx, "Unexpected 1D/3D compressed texsubimage call");
4493       return;
4494    }
4495
4496    _mesa_get_format_block_size(texFormat, &bw, &bh);
4497
4498    /* get pointer to src pixels (may be in a pbo which we'll map here) */
4499    data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
4500                                                  &ctx->Unpack,
4501                                                  "glCompressedTexSubImage2D");
4502    if (!data)
4503       return;
4504
4505    srcRowStride = _mesa_format_row_stride(texFormat, width);
4506    src = (const GLubyte *) data;
4507
4508    /* Map dest texture buffer */
4509    ctx->Driver.MapTextureImage(ctx, texImage, 0,
4510                                xoffset, yoffset, width, height,
4511                                GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
4512                                &dstMap, &dstRowStride);
4513
4514    if (dstMap) {
4515       bytesPerRow = srcRowStride;  /* bytes per row of blocks */
4516       rows = (height + bh - 1) / bh;  /* rows in blocks */
4517
4518       /* copy rows of blocks */
4519       for (i = 0; i < rows; i++) {
4520          memcpy(dstMap, src, bytesPerRow);
4521          dstMap += dstRowStride;
4522          src += srcRowStride;
4523       }
4524
4525       ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4526    }
4527    else {
4528       _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage2D");
4529    }
4530
4531    _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
4532 }