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