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