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