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