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