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