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