OSDN Git Service

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