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