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