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