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