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