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