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