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