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