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