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