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