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