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