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