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