mesa/format: add mesa MESA_FORMAT_ARGB2101010_UINT support.
[mesa.git] / src / mesa / main / texstore.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /*
27 * Authors:
28 * Brian Paul
29 */
30
31 /**
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
35 * texture image data.
36 *
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
39 * code:
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
43 * etc...
44 *
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
47 * pixel unpacking
48 * pixel transfer (scale, bais, lookup, etc)
49 *
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
52 */
53
54
55 #include "glheader.h"
56 #include "bufferobj.h"
57 #include "colormac.h"
58 #include "image.h"
59 #include "macros.h"
60 #include "mipmap.h"
61 #include "mfeatures.h"
62 #include "mtypes.h"
63 #include "pack.h"
64 #include "pbo.h"
65 #include "imports.h"
66 #include "texcompress.h"
67 #include "texcompress_fxt1.h"
68 #include "texcompress_rgtc.h"
69 #include "texcompress_s3tc.h"
70 #include "teximage.h"
71 #include "texstore.h"
72 #include "enums.h"
73 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
74 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
75
76
77 enum {
78 ZERO = 4,
79 ONE = 5
80 };
81
82
83 /**
84 * Texture image storage function.
85 */
86 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
87
88
89 /**
90 * Return GL_TRUE if the given image format is one that be converted
91 * to another format by swizzling.
92 */
93 static GLboolean
94 can_swizzle(GLenum logicalBaseFormat)
95 {
96 switch (logicalBaseFormat) {
97 case GL_RGBA:
98 case GL_RGB:
99 case GL_LUMINANCE_ALPHA:
100 case GL_INTENSITY:
101 case GL_ALPHA:
102 case GL_LUMINANCE:
103 case GL_RED:
104 case GL_GREEN:
105 case GL_BLUE:
106 case GL_BGR:
107 case GL_BGRA:
108 case GL_ABGR_EXT:
109 case GL_RG:
110 return GL_TRUE;
111 default:
112 return GL_FALSE;
113 }
114 }
115
116
117
118 enum {
119 IDX_LUMINANCE = 0,
120 IDX_ALPHA,
121 IDX_INTENSITY,
122 IDX_LUMINANCE_ALPHA,
123 IDX_RGB,
124 IDX_RGBA,
125 IDX_RED,
126 IDX_GREEN,
127 IDX_BLUE,
128 IDX_BGR,
129 IDX_BGRA,
130 IDX_ABGR,
131 IDX_RG,
132 MAX_IDX
133 };
134
135 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
136 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
137 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
138 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
139
140
141 static const struct {
142 GLubyte format_idx;
143 GLubyte to_rgba[6];
144 GLubyte from_rgba[6];
145 } mappings[MAX_IDX] =
146 {
147 {
148 IDX_LUMINANCE,
149 MAP4(0,0,0,ONE),
150 MAP1(0)
151 },
152
153 {
154 IDX_ALPHA,
155 MAP4(ZERO, ZERO, ZERO, 0),
156 MAP1(3)
157 },
158
159 {
160 IDX_INTENSITY,
161 MAP4(0, 0, 0, 0),
162 MAP1(0),
163 },
164
165 {
166 IDX_LUMINANCE_ALPHA,
167 MAP4(0,0,0,1),
168 MAP2(0,3)
169 },
170
171 {
172 IDX_RGB,
173 MAP4(0,1,2,ONE),
174 MAP3(0,1,2)
175 },
176
177 {
178 IDX_RGBA,
179 MAP4(0,1,2,3),
180 MAP4(0,1,2,3),
181 },
182
183 {
184 IDX_RED,
185 MAP4(0, ZERO, ZERO, ONE),
186 MAP1(0),
187 },
188
189 {
190 IDX_GREEN,
191 MAP4(ZERO, 0, ZERO, ONE),
192 MAP1(1),
193 },
194
195 {
196 IDX_BLUE,
197 MAP4(ZERO, ZERO, 0, ONE),
198 MAP1(2),
199 },
200
201 {
202 IDX_BGR,
203 MAP4(2,1,0,ONE),
204 MAP3(2,1,0)
205 },
206
207 {
208 IDX_BGRA,
209 MAP4(2,1,0,3),
210 MAP4(2,1,0,3)
211 },
212
213 {
214 IDX_ABGR,
215 MAP4(3,2,1,0),
216 MAP4(3,2,1,0)
217 },
218
219 {
220 IDX_RG,
221 MAP4(0, 1, ZERO, ONE),
222 MAP2(0, 1)
223 },
224 };
225
226
227
228 /**
229 * Convert a GL image format enum to an IDX_* value (see above).
230 */
231 static int
232 get_map_idx(GLenum value)
233 {
234 switch (value) {
235 case GL_LUMINANCE: return IDX_LUMINANCE;
236 case GL_ALPHA: return IDX_ALPHA;
237 case GL_INTENSITY: return IDX_INTENSITY;
238 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
239 case GL_RGB: return IDX_RGB;
240 case GL_RGBA: return IDX_RGBA;
241 case GL_RED: return IDX_RED;
242 case GL_GREEN: return IDX_GREEN;
243 case GL_BLUE: return IDX_BLUE;
244 case GL_BGR: return IDX_BGR;
245 case GL_BGRA: return IDX_BGRA;
246 case GL_ABGR_EXT: return IDX_ABGR;
247 case GL_RG: return IDX_RG;
248 default:
249 _mesa_problem(NULL, "Unexpected inFormat");
250 return 0;
251 }
252 }
253
254
255 /**
256 * When promoting texture formats (see below) we need to compute the
257 * mapping of dest components back to source components.
258 * This function does that.
259 * \param inFormat the incoming format of the texture
260 * \param outFormat the final texture format
261 * \return map[6] a full 6-component map
262 */
263 static void
264 compute_component_mapping(GLenum inFormat, GLenum outFormat,
265 GLubyte *map)
266 {
267 const int inFmt = get_map_idx(inFormat);
268 const int outFmt = get_map_idx(outFormat);
269 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
270 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
271 int i;
272
273 for (i = 0; i < 4; i++)
274 map[i] = in2rgba[rgba2out[i]];
275
276 map[ZERO] = ZERO;
277 map[ONE] = ONE;
278
279 #if 0
280 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
281 inFormat, _mesa_lookup_enum_by_nr(inFormat),
282 outFormat, _mesa_lookup_enum_by_nr(outFormat),
283 map[0],
284 map[1],
285 map[2],
286 map[3],
287 map[4],
288 map[5]);
289 #endif
290 }
291
292
293 /**
294 * Make a temporary (color) texture image with GLfloat components.
295 * Apply all needed pixel unpacking and pixel transfer operations.
296 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
297 * Suppose the user specifies GL_LUMINANCE as the internal texture format
298 * but the graphics hardware doesn't support luminance textures. So, we might
299 * use an RGB hardware format instead.
300 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
301 *
302 * \param ctx the rendering context
303 * \param dims image dimensions: 1, 2 or 3
304 * \param logicalBaseFormat basic texture derived from the user's
305 * internal texture format value
306 * \param textureBaseFormat the actual basic format of the texture
307 * \param srcWidth source image width
308 * \param srcHeight source image height
309 * \param srcDepth source image depth
310 * \param srcFormat source image format
311 * \param srcType source image type
312 * \param srcAddr source image address
313 * \param srcPacking source image pixel packing
314 * \return resulting image with format = textureBaseFormat and type = GLfloat.
315 */
316 GLfloat *
317 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
318 GLenum logicalBaseFormat,
319 GLenum textureBaseFormat,
320 GLint srcWidth, GLint srcHeight, GLint srcDepth,
321 GLenum srcFormat, GLenum srcType,
322 const GLvoid *srcAddr,
323 const struct gl_pixelstore_attrib *srcPacking,
324 GLbitfield transferOps)
325 {
326 GLfloat *tempImage;
327 const GLint components = _mesa_components_in_format(logicalBaseFormat);
328 const GLint srcStride =
329 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
330 GLfloat *dst;
331 GLint img, row;
332
333 ASSERT(dims >= 1 && dims <= 3);
334
335 ASSERT(logicalBaseFormat == GL_RGBA ||
336 logicalBaseFormat == GL_RGB ||
337 logicalBaseFormat == GL_RG ||
338 logicalBaseFormat == GL_RED ||
339 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
340 logicalBaseFormat == GL_LUMINANCE ||
341 logicalBaseFormat == GL_ALPHA ||
342 logicalBaseFormat == GL_INTENSITY ||
343 logicalBaseFormat == GL_DEPTH_COMPONENT);
344
345 ASSERT(textureBaseFormat == GL_RGBA ||
346 textureBaseFormat == GL_RGB ||
347 textureBaseFormat == GL_RG ||
348 textureBaseFormat == GL_RED ||
349 textureBaseFormat == GL_LUMINANCE_ALPHA ||
350 textureBaseFormat == GL_LUMINANCE ||
351 textureBaseFormat == GL_ALPHA ||
352 textureBaseFormat == GL_INTENSITY ||
353 textureBaseFormat == GL_DEPTH_COMPONENT);
354
355 tempImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
356 * components * sizeof(GLfloat));
357 if (!tempImage)
358 return NULL;
359
360 dst = tempImage;
361 for (img = 0; img < srcDepth; img++) {
362 const GLubyte *src
363 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
364 srcWidth, srcHeight,
365 srcFormat, srcType,
366 img, 0, 0);
367 for (row = 0; row < srcHeight; row++) {
368 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
369 dst, srcFormat, srcType, src,
370 srcPacking, transferOps);
371 dst += srcWidth * components;
372 src += srcStride;
373 }
374 }
375
376 if (logicalBaseFormat != textureBaseFormat) {
377 /* more work */
378 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
379 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
380 GLfloat *newImage;
381 GLint i, n;
382 GLubyte map[6];
383
384 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
385 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
386 textureBaseFormat == GL_LUMINANCE_ALPHA);
387
388 /* The actual texture format should have at least as many components
389 * as the logical texture format.
390 */
391 ASSERT(texComponents >= logComponents);
392
393 newImage = (GLfloat *) malloc(srcWidth * srcHeight * srcDepth
394 * texComponents * sizeof(GLfloat));
395 if (!newImage) {
396 free(tempImage);
397 return NULL;
398 }
399
400 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
401
402 n = srcWidth * srcHeight * srcDepth;
403 for (i = 0; i < n; i++) {
404 GLint k;
405 for (k = 0; k < texComponents; k++) {
406 GLint j = map[k];
407 if (j == ZERO)
408 newImage[i * texComponents + k] = 0.0F;
409 else if (j == ONE)
410 newImage[i * texComponents + k] = 1.0F;
411 else
412 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
413 }
414 }
415
416 free(tempImage);
417 tempImage = newImage;
418 }
419
420 return tempImage;
421 }
422
423
424 /**
425 * Make temporary image with uint pixel values. Used for unsigned
426 * integer-valued textures.
427 */
428 static GLuint *
429 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
430 GLenum logicalBaseFormat,
431 GLenum textureBaseFormat,
432 GLint srcWidth, GLint srcHeight, GLint srcDepth,
433 GLenum srcFormat, GLenum srcType,
434 const GLvoid *srcAddr,
435 const struct gl_pixelstore_attrib *srcPacking)
436 {
437 GLuint *tempImage;
438 const GLint components = _mesa_components_in_format(logicalBaseFormat);
439 const GLint srcStride =
440 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
441 GLuint *dst;
442 GLint img, row;
443
444 ASSERT(dims >= 1 && dims <= 3);
445
446 ASSERT(logicalBaseFormat == GL_RGBA ||
447 logicalBaseFormat == GL_RGB ||
448 logicalBaseFormat == GL_RG ||
449 logicalBaseFormat == GL_RED ||
450 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
451 logicalBaseFormat == GL_LUMINANCE ||
452 logicalBaseFormat == GL_INTENSITY ||
453 logicalBaseFormat == GL_ALPHA);
454
455 ASSERT(textureBaseFormat == GL_RGBA ||
456 textureBaseFormat == GL_RGB ||
457 textureBaseFormat == GL_RG ||
458 textureBaseFormat == GL_RED ||
459 textureBaseFormat == GL_LUMINANCE_ALPHA ||
460 textureBaseFormat == GL_LUMINANCE ||
461 textureBaseFormat == GL_INTENSITY ||
462 textureBaseFormat == GL_ALPHA);
463
464 tempImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
465 * components * sizeof(GLuint));
466 if (!tempImage)
467 return NULL;
468
469 dst = tempImage;
470 for (img = 0; img < srcDepth; img++) {
471 const GLubyte *src
472 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
473 srcWidth, srcHeight,
474 srcFormat, srcType,
475 img, 0, 0);
476 for (row = 0; row < srcHeight; row++) {
477 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
478 dst, srcFormat, srcType, src,
479 srcPacking);
480 dst += srcWidth * components;
481 src += srcStride;
482 }
483 }
484
485 if (logicalBaseFormat != textureBaseFormat) {
486 /* more work */
487 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
488 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
489 GLuint *newImage;
490 GLint i, n;
491 GLubyte map[6];
492
493 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
494 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
495 textureBaseFormat == GL_LUMINANCE_ALPHA);
496
497 /* The actual texture format should have at least as many components
498 * as the logical texture format.
499 */
500 ASSERT(texComponents >= logComponents);
501
502 newImage = (GLuint *) malloc(srcWidth * srcHeight * srcDepth
503 * texComponents * sizeof(GLuint));
504 if (!newImage) {
505 free(tempImage);
506 return NULL;
507 }
508
509 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
510
511 n = srcWidth * srcHeight * srcDepth;
512 for (i = 0; i < n; i++) {
513 GLint k;
514 for (k = 0; k < texComponents; k++) {
515 GLint j = map[k];
516 if (j == ZERO)
517 newImage[i * texComponents + k] = 0.0F;
518 else if (j == ONE)
519 newImage[i * texComponents + k] = 1.0F;
520 else
521 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
522 }
523 }
524
525 free(tempImage);
526 tempImage = newImage;
527 }
528
529 return tempImage;
530 }
531
532
533
534 /**
535 * Make a temporary (color) texture image with GLubyte components.
536 * Apply all needed pixel unpacking and pixel transfer operations.
537 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
538 * Suppose the user specifies GL_LUMINANCE as the internal texture format
539 * but the graphics hardware doesn't support luminance textures. So, we might
540 * use an RGB hardware format instead.
541 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
542 *
543 * \param ctx the rendering context
544 * \param dims image dimensions: 1, 2 or 3
545 * \param logicalBaseFormat basic texture derived from the user's
546 * internal texture format value
547 * \param textureBaseFormat the actual basic format of the texture
548 * \param srcWidth source image width
549 * \param srcHeight source image height
550 * \param srcDepth source image depth
551 * \param srcFormat source image format
552 * \param srcType source image type
553 * \param srcAddr source image address
554 * \param srcPacking source image pixel packing
555 * \return resulting image with format = textureBaseFormat and type = GLubyte.
556 */
557 GLubyte *
558 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
559 GLenum logicalBaseFormat,
560 GLenum textureBaseFormat,
561 GLint srcWidth, GLint srcHeight, GLint srcDepth,
562 GLenum srcFormat, GLenum srcType,
563 const GLvoid *srcAddr,
564 const struct gl_pixelstore_attrib *srcPacking)
565 {
566 GLuint transferOps = ctx->_ImageTransferState;
567 const GLint components = _mesa_components_in_format(logicalBaseFormat);
568 GLint img, row;
569 GLubyte *tempImage, *dst;
570
571 ASSERT(dims >= 1 && dims <= 3);
572
573 ASSERT(logicalBaseFormat == GL_RGBA ||
574 logicalBaseFormat == GL_RGB ||
575 logicalBaseFormat == GL_RG ||
576 logicalBaseFormat == GL_RED ||
577 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
578 logicalBaseFormat == GL_LUMINANCE ||
579 logicalBaseFormat == GL_ALPHA ||
580 logicalBaseFormat == GL_INTENSITY);
581
582 ASSERT(textureBaseFormat == GL_RGBA ||
583 textureBaseFormat == GL_RGB ||
584 textureBaseFormat == GL_RG ||
585 textureBaseFormat == GL_RED ||
586 textureBaseFormat == GL_LUMINANCE_ALPHA ||
587 textureBaseFormat == GL_LUMINANCE ||
588 textureBaseFormat == GL_ALPHA ||
589 textureBaseFormat == GL_INTENSITY);
590
591 /* unpack and transfer the source image */
592 tempImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
593 * components * sizeof(GLubyte));
594 if (!tempImage) {
595 return NULL;
596 }
597
598 dst = tempImage;
599 for (img = 0; img < srcDepth; img++) {
600 const GLint srcStride =
601 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
602 const GLubyte *src =
603 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
604 srcWidth, srcHeight,
605 srcFormat, srcType,
606 img, 0, 0);
607 for (row = 0; row < srcHeight; row++) {
608 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
609 srcFormat, srcType, src, srcPacking,
610 transferOps);
611 dst += srcWidth * components;
612 src += srcStride;
613 }
614 }
615
616 if (logicalBaseFormat != textureBaseFormat) {
617 /* one more conversion step */
618 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
619 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
620 GLubyte *newImage;
621 GLint i, n;
622 GLubyte map[6];
623
624 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
625 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
626 textureBaseFormat == GL_LUMINANCE_ALPHA);
627
628 /* The actual texture format should have at least as many components
629 * as the logical texture format.
630 */
631 ASSERT(texComponents >= logComponents);
632
633 newImage = (GLubyte *) malloc(srcWidth * srcHeight * srcDepth
634 * texComponents * sizeof(GLubyte));
635 if (!newImage) {
636 free(tempImage);
637 return NULL;
638 }
639
640 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
641
642 n = srcWidth * srcHeight * srcDepth;
643 for (i = 0; i < n; i++) {
644 GLint k;
645 for (k = 0; k < texComponents; k++) {
646 GLint j = map[k];
647 if (j == ZERO)
648 newImage[i * texComponents + k] = 0;
649 else if (j == ONE)
650 newImage[i * texComponents + k] = 255;
651 else
652 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
653 }
654 }
655
656 free(tempImage);
657 tempImage = newImage;
658 }
659
660 return tempImage;
661 }
662
663
664 /**
665 * Copy GLubyte pixels from <src> to <dst> with swizzling.
666 * \param dst destination pixels
667 * \param dstComponents number of color components in destination pixels
668 * \param src source pixels
669 * \param srcComponents number of color components in source pixels
670 * \param map the swizzle mapping. map[X] says where to find the X component
671 * in the source image's pixels. For example, if the source image
672 * is GL_BGRA and X = red, map[0] yields 2.
673 * \param count number of pixels to copy/swizzle.
674 */
675 static void
676 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
677 GLuint srcComponents, const GLubyte *map, GLuint count)
678 {
679 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
680 do { \
681 GLuint i; \
682 for (i = 0; i < count; i++) { \
683 GLuint j; \
684 if (srcComps == 4) { \
685 COPY_4UBV(tmp, src); \
686 } \
687 else { \
688 for (j = 0; j < srcComps; j++) { \
689 tmp[j] = src[j]; \
690 } \
691 } \
692 src += srcComps; \
693 for (j = 0; j < dstComps; j++) { \
694 dst[j] = tmp[map[j]]; \
695 } \
696 dst += dstComps; \
697 } \
698 } while (0)
699
700 GLubyte tmp[6];
701
702 tmp[ZERO] = 0x0;
703 tmp[ONE] = 0xff;
704
705 ASSERT(srcComponents <= 4);
706 ASSERT(dstComponents <= 4);
707
708 switch (dstComponents) {
709 case 4:
710 switch (srcComponents) {
711 case 4:
712 SWZ_CPY(dst, src, count, 4, 4);
713 break;
714 case 3:
715 SWZ_CPY(dst, src, count, 4, 3);
716 break;
717 case 2:
718 SWZ_CPY(dst, src, count, 4, 2);
719 break;
720 case 1:
721 SWZ_CPY(dst, src, count, 4, 1);
722 break;
723 default:
724 ;
725 }
726 break;
727 case 3:
728 switch (srcComponents) {
729 case 4:
730 SWZ_CPY(dst, src, count, 3, 4);
731 break;
732 case 3:
733 SWZ_CPY(dst, src, count, 3, 3);
734 break;
735 case 2:
736 SWZ_CPY(dst, src, count, 3, 2);
737 break;
738 case 1:
739 SWZ_CPY(dst, src, count, 3, 1);
740 break;
741 default:
742 ;
743 }
744 break;
745 case 2:
746 switch (srcComponents) {
747 case 4:
748 SWZ_CPY(dst, src, count, 2, 4);
749 break;
750 case 3:
751 SWZ_CPY(dst, src, count, 2, 3);
752 break;
753 case 2:
754 SWZ_CPY(dst, src, count, 2, 2);
755 break;
756 case 1:
757 SWZ_CPY(dst, src, count, 2, 1);
758 break;
759 default:
760 ;
761 }
762 break;
763 case 1:
764 switch (srcComponents) {
765 case 4:
766 SWZ_CPY(dst, src, count, 1, 4);
767 break;
768 case 3:
769 SWZ_CPY(dst, src, count, 1, 3);
770 break;
771 case 2:
772 SWZ_CPY(dst, src, count, 1, 2);
773 break;
774 case 1:
775 SWZ_CPY(dst, src, count, 1, 1);
776 break;
777 default:
778 ;
779 }
780 break;
781 default:
782 ;
783 }
784 #undef SWZ_CPY
785 }
786
787
788
789 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
790 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
791
792
793 /**
794 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
795 * mapping array depending on endianness.
796 */
797 static const GLubyte *
798 type_mapping( GLenum srcType )
799 {
800 switch (srcType) {
801 case GL_BYTE:
802 case GL_UNSIGNED_BYTE:
803 return map_identity;
804 case GL_UNSIGNED_INT_8_8_8_8:
805 return _mesa_little_endian() ? map_3210 : map_identity;
806 case GL_UNSIGNED_INT_8_8_8_8_REV:
807 return _mesa_little_endian() ? map_identity : map_3210;
808 default:
809 return NULL;
810 }
811 }
812
813
814 /**
815 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
816 * mapping array depending on pixelstore byte swapping state.
817 */
818 static const GLubyte *
819 byteswap_mapping( GLboolean swapBytes,
820 GLenum srcType )
821 {
822 if (!swapBytes)
823 return map_identity;
824
825 switch (srcType) {
826 case GL_BYTE:
827 case GL_UNSIGNED_BYTE:
828 return map_identity;
829 case GL_UNSIGNED_INT_8_8_8_8:
830 case GL_UNSIGNED_INT_8_8_8_8_REV:
831 return map_3210;
832 default:
833 return NULL;
834 }
835 }
836
837
838
839 /**
840 * Transfer a GLubyte texture image with component swizzling.
841 */
842 static void
843 _mesa_swizzle_ubyte_image(struct gl_context *ctx,
844 GLuint dimensions,
845 GLenum srcFormat,
846 GLenum srcType,
847
848 GLenum baseInternalFormat,
849
850 const GLubyte *rgba2dst,
851 GLuint dstComponents,
852
853 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
854 GLint dstRowStride,
855 GLubyte **dstSlices,
856
857 GLint srcWidth, GLint srcHeight, GLint srcDepth,
858 const GLvoid *srcAddr,
859 const struct gl_pixelstore_attrib *srcPacking )
860 {
861 GLint srcComponents = _mesa_components_in_format(srcFormat);
862 const GLubyte *srctype2ubyte, *swap;
863 GLubyte map[4], src2base[6], base2rgba[6];
864 GLint i;
865 const GLint srcRowStride =
866 _mesa_image_row_stride(srcPacking, srcWidth,
867 srcFormat, GL_UNSIGNED_BYTE);
868 const GLint srcImageStride
869 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
870 GL_UNSIGNED_BYTE);
871 const GLubyte *srcImage
872 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
873 srcWidth, srcHeight, srcFormat,
874 GL_UNSIGNED_BYTE, 0, 0, 0);
875
876 (void) ctx;
877
878 /* Translate from src->baseInternal->GL_RGBA->dst. This will
879 * correctly deal with RGBA->RGB->RGBA conversions where the final
880 * A value must be 0xff regardless of the incoming alpha values.
881 */
882 compute_component_mapping(srcFormat, baseInternalFormat, src2base);
883 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
884 swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
885 srctype2ubyte = type_mapping(srcType);
886
887
888 for (i = 0; i < 4; i++)
889 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
890
891 /* printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
892
893 if (srcComponents == dstComponents &&
894 srcRowStride == dstRowStride &&
895 srcRowStride == srcWidth * srcComponents &&
896 dimensions < 3) {
897 /* 1 and 2D images only */
898 GLubyte *dstImage = dstSlices[0]
899 + dstYoffset * dstRowStride
900 + dstXoffset * dstComponents;
901 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
902 srcWidth * srcHeight);
903 }
904 else {
905 GLint img, row;
906 for (img = 0; img < srcDepth; img++) {
907 const GLubyte *srcRow = srcImage;
908 GLubyte *dstRow = dstSlices[dstZoffset + img]
909 + dstYoffset * dstRowStride
910 + dstXoffset * dstComponents;
911 for (row = 0; row < srcHeight; row++) {
912 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
913 dstRow += dstRowStride;
914 srcRow += srcRowStride;
915 }
916 srcImage += srcImageStride;
917 }
918 }
919 }
920
921
922 /**
923 * Teximage storage routine for when a simple memcpy will do.
924 * No pixel transfer operations or special texel encodings allowed.
925 * 1D, 2D and 3D images supported.
926 */
927 static void
928 memcpy_texture(struct gl_context *ctx,
929 GLuint dimensions,
930 gl_format dstFormat,
931 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
932 GLint dstRowStride,
933 GLubyte **dstSlices,
934 GLint srcWidth, GLint srcHeight, GLint srcDepth,
935 GLenum srcFormat, GLenum srcType,
936 const GLvoid *srcAddr,
937 const struct gl_pixelstore_attrib *srcPacking)
938 {
939 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
940 srcFormat, srcType);
941 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
942 srcWidth, srcHeight, srcFormat, srcType);
943 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
944 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
945 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
946 const GLint bytesPerRow = srcWidth * texelBytes;
947
948 if (dstRowStride == srcRowStride &&
949 dstRowStride == bytesPerRow) {
950 /* memcpy image by image */
951 GLint img;
952 for (img = 0; img < srcDepth; img++) {
953 GLubyte *dstImage = dstSlices[dstZoffset + img]
954 + dstYoffset * dstRowStride
955 + dstXoffset * texelBytes;
956 ctx->Driver.TextureMemCpy(dstImage, srcImage,
957 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 ctx->Driver.TextureMemCpy(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_RG88 ||
2145 dstFormat == MESA_FORMAT_RG88_REV);
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_RG88 &&
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_RG88) ||
2186 (!littleEndian && dstFormat == MESA_FORMAT_RG88_REV)) {
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_RG88) {
2228 for (col = 0; col < srcWidth; col++) {
2229 /* src[0] is luminance, src[1] is alpha */
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, src[1] is alpha */
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_ALPHA ||
3572 baseInternalFormat == GL_LUMINANCE ||
3573 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3574 baseInternalFormat == GL_INTENSITY);
3575 ASSERT(texelBytes == components * sizeof(GLbyte));
3576
3577 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3578 * to integer formats.
3579 */
3580 if (!srcPacking->SwapBytes &&
3581 baseInternalFormat == srcFormat &&
3582 srcType == GL_BYTE) {
3583 /* simple memcpy path */
3584 memcpy_texture(ctx, dims,
3585 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3586 dstRowStride, dstSlices,
3587 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3588 srcAddr, srcPacking);
3589 }
3590 else {
3591 /* general path */
3592 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3593 baseInternalFormat,
3594 baseFormat,
3595 srcWidth, srcHeight, srcDepth,
3596 srcFormat, srcType, srcAddr,
3597 srcPacking, 0x0);
3598 const GLfloat *src = tempImage;
3599 GLint img, row;
3600 if (!tempImage)
3601 return GL_FALSE;
3602 for (img = 0; img < srcDepth; img++) {
3603 GLubyte *dstRow = dstSlices[dstZoffset + img]
3604 + dstYoffset * dstRowStride
3605 + dstXoffset * texelBytes;
3606 for (row = 0; row < srcHeight; row++) {
3607 GLbyte *dstTexel = (GLbyte *) dstRow;
3608 GLint i;
3609 for (i = 0; i < srcWidth * components; i++) {
3610 dstTexel[i] = (GLbyte) src[i];
3611 }
3612 dstRow += dstRowStride;
3613 src += srcWidth * components;
3614 }
3615 }
3616
3617 free((void *) tempImage);
3618 }
3619 return GL_TRUE;
3620 }
3621
3622
3623 /* non-normalized, signed int16 */
3624 static GLboolean
3625 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
3626 {
3627 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3628 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3629 const GLint components = _mesa_components_in_format(baseFormat);
3630
3631 ASSERT(dstFormat == MESA_FORMAT_R_INT16 ||
3632 dstFormat == MESA_FORMAT_RG_INT16 ||
3633 dstFormat == MESA_FORMAT_RGB_INT16 ||
3634 dstFormat == MESA_FORMAT_RGBA_INT16 ||
3635 dstFormat == MESA_FORMAT_ALPHA_INT16 ||
3636 dstFormat == MESA_FORMAT_LUMINANCE_INT16 ||
3637 dstFormat == MESA_FORMAT_INTENSITY_INT16 ||
3638 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT16);
3639 ASSERT(baseInternalFormat == GL_RGBA ||
3640 baseInternalFormat == GL_RGB ||
3641 baseInternalFormat == GL_ALPHA ||
3642 baseInternalFormat == GL_LUMINANCE ||
3643 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3644 baseInternalFormat == GL_INTENSITY);
3645 ASSERT(texelBytes == components * sizeof(GLshort));
3646
3647 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3648 * to integer formats.
3649 */
3650 if (!srcPacking->SwapBytes &&
3651 baseInternalFormat == srcFormat &&
3652 srcType == GL_SHORT) {
3653 /* simple memcpy path */
3654 memcpy_texture(ctx, dims,
3655 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3656 dstRowStride, dstSlices,
3657 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3658 srcAddr, srcPacking);
3659 }
3660 else {
3661 /* general path */
3662 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3663 baseInternalFormat,
3664 baseFormat,
3665 srcWidth, srcHeight, srcDepth,
3666 srcFormat, srcType, srcAddr,
3667 srcPacking, 0x0);
3668 const GLfloat *src = tempImage;
3669 GLint img, row;
3670 if (!tempImage)
3671 return GL_FALSE;
3672 for (img = 0; img < srcDepth; img++) {
3673 GLubyte *dstRow = dstSlices[dstZoffset + img]
3674 + dstYoffset * dstRowStride
3675 + dstXoffset * texelBytes;
3676 for (row = 0; row < srcHeight; row++) {
3677 GLshort *dstTexel = (GLshort *) dstRow;
3678 GLint i;
3679 for (i = 0; i < srcWidth * components; i++) {
3680 dstTexel[i] = (GLint) src[i];
3681 }
3682 dstRow += dstRowStride;
3683 src += srcWidth * components;
3684 }
3685 }
3686
3687 free((void *) tempImage);
3688 }
3689 return GL_TRUE;
3690 }
3691
3692
3693 /* non-normalized, signed int32 */
3694 static GLboolean
3695 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
3696 {
3697 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3698 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3699 const GLint components = _mesa_components_in_format(baseFormat);
3700
3701 ASSERT(dstFormat == MESA_FORMAT_R_INT32 ||
3702 dstFormat == MESA_FORMAT_RG_INT32 ||
3703 dstFormat == MESA_FORMAT_RGB_INT32 ||
3704 dstFormat == MESA_FORMAT_RGBA_INT32 ||
3705 dstFormat == MESA_FORMAT_ALPHA_INT32 ||
3706 dstFormat == MESA_FORMAT_INTENSITY_INT32 ||
3707 dstFormat == MESA_FORMAT_LUMINANCE_INT32 ||
3708 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_INT32);
3709 ASSERT(baseInternalFormat == GL_RGBA ||
3710 baseInternalFormat == GL_RGB ||
3711 baseInternalFormat == GL_ALPHA ||
3712 baseInternalFormat == GL_LUMINANCE ||
3713 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3714 baseInternalFormat == GL_INTENSITY);
3715 ASSERT(texelBytes == components * sizeof(GLint));
3716
3717 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3718 * to integer formats.
3719 */
3720 if (!srcPacking->SwapBytes &&
3721 baseInternalFormat == srcFormat &&
3722 srcType == GL_INT) {
3723 /* simple memcpy path */
3724 memcpy_texture(ctx, dims,
3725 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3726 dstRowStride, dstSlices,
3727 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3728 srcAddr, srcPacking);
3729 }
3730 else {
3731 /* general path */
3732 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3733 baseInternalFormat,
3734 baseFormat,
3735 srcWidth, srcHeight, srcDepth,
3736 srcFormat, srcType, srcAddr,
3737 srcPacking, 0x0);
3738 const GLfloat *src = tempImage;
3739 GLint img, row;
3740 if (!tempImage)
3741 return GL_FALSE;
3742 for (img = 0; img < srcDepth; img++) {
3743 GLubyte *dstRow = dstSlices[dstZoffset + img]
3744 + dstYoffset * dstRowStride
3745 + dstXoffset * texelBytes;
3746 for (row = 0; row < srcHeight; row++) {
3747 GLint *dstTexel = (GLint *) dstRow;
3748 GLint i;
3749 for (i = 0; i < srcWidth * components; i++) {
3750 dstTexel[i] = (GLint) src[i];
3751 }
3752 dstRow += dstRowStride;
3753 src += srcWidth * components;
3754 }
3755 }
3756
3757 free((void *) tempImage);
3758 }
3759 return GL_TRUE;
3760 }
3761
3762
3763 /* non-normalized, unsigned int8 */
3764 static GLboolean
3765 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3766 {
3767 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3768 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3769 const GLint components = _mesa_components_in_format(baseFormat);
3770
3771 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
3772 dstFormat == MESA_FORMAT_RG_UINT8 ||
3773 dstFormat == MESA_FORMAT_RGB_UINT8 ||
3774 dstFormat == MESA_FORMAT_RGBA_UINT8 ||
3775 dstFormat == MESA_FORMAT_ALPHA_UINT8 ||
3776 dstFormat == MESA_FORMAT_INTENSITY_UINT8 ||
3777 dstFormat == MESA_FORMAT_LUMINANCE_UINT8 ||
3778 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT8);
3779 ASSERT(baseInternalFormat == GL_RGBA ||
3780 baseInternalFormat == GL_RGB ||
3781 baseInternalFormat == GL_ALPHA ||
3782 baseInternalFormat == GL_LUMINANCE ||
3783 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3784 baseInternalFormat == GL_INTENSITY);
3785 ASSERT(texelBytes == components * sizeof(GLubyte));
3786
3787 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3788 * to integer formats.
3789 */
3790 if (!srcPacking->SwapBytes &&
3791 baseInternalFormat == srcFormat &&
3792 srcType == GL_UNSIGNED_BYTE) {
3793 /* simple memcpy path */
3794 memcpy_texture(ctx, dims,
3795 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3796 dstRowStride, dstSlices,
3797 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3798 srcAddr, srcPacking);
3799 }
3800 else {
3801 /* general path */
3802 const GLuint *tempImage =
3803 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3804 srcWidth, srcHeight, srcDepth,
3805 srcFormat, srcType, srcAddr, srcPacking);
3806 const GLuint *src = tempImage;
3807 GLint img, row;
3808 if (!tempImage)
3809 return GL_FALSE;
3810 for (img = 0; img < srcDepth; img++) {
3811 GLubyte *dstRow = dstSlices[dstZoffset + img]
3812 + dstYoffset * dstRowStride
3813 + dstXoffset * texelBytes;
3814 for (row = 0; row < srcHeight; row++) {
3815 GLubyte *dstTexel = (GLubyte *) dstRow;
3816 GLint i;
3817 for (i = 0; i < srcWidth * components; i++) {
3818 dstTexel[i] = (GLubyte) CLAMP(src[i], 0, 0xff);
3819 }
3820 dstRow += dstRowStride;
3821 src += srcWidth * components;
3822 }
3823 }
3824
3825 free((void *) tempImage);
3826 }
3827 return GL_TRUE;
3828 }
3829
3830
3831 /* non-normalized, unsigned int16 */
3832 static GLboolean
3833 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3834 {
3835 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3836 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3837 const GLint components = _mesa_components_in_format(baseFormat);
3838
3839 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
3840 dstFormat == MESA_FORMAT_RG_UINT16 ||
3841 dstFormat == MESA_FORMAT_RGB_UINT16 ||
3842 dstFormat == MESA_FORMAT_RGBA_UINT16 ||
3843 dstFormat == MESA_FORMAT_ALPHA_UINT16 ||
3844 dstFormat == MESA_FORMAT_INTENSITY_UINT16 ||
3845 dstFormat == MESA_FORMAT_LUMINANCE_UINT16 ||
3846 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT16);
3847 ASSERT(baseInternalFormat == GL_RGBA ||
3848 baseInternalFormat == GL_RGB ||
3849 baseInternalFormat == GL_ALPHA ||
3850 baseInternalFormat == GL_LUMINANCE ||
3851 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3852 baseInternalFormat == GL_INTENSITY);
3853 ASSERT(texelBytes == components * sizeof(GLushort));
3854
3855 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3856 * to integer formats.
3857 */
3858 if (!srcPacking->SwapBytes &&
3859 baseInternalFormat == srcFormat &&
3860 srcType == GL_UNSIGNED_SHORT) {
3861 /* simple memcpy path */
3862 memcpy_texture(ctx, dims,
3863 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3864 dstRowStride, dstSlices,
3865 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3866 srcAddr, srcPacking);
3867 }
3868 else {
3869 /* general path */
3870 const GLuint *tempImage =
3871 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3872 srcWidth, srcHeight, srcDepth,
3873 srcFormat, srcType, srcAddr, srcPacking);
3874 const GLuint *src = tempImage;
3875 GLint img, row;
3876 if (!tempImage)
3877 return GL_FALSE;
3878 for (img = 0; img < srcDepth; img++) {
3879 GLubyte *dstRow = dstSlices[dstZoffset + img]
3880 + dstYoffset * dstRowStride
3881 + dstXoffset * texelBytes;
3882 for (row = 0; row < srcHeight; row++) {
3883 GLushort *dstTexel = (GLushort *) dstRow;
3884 GLint i;
3885 for (i = 0; i < srcWidth * components; i++) {
3886 dstTexel[i] = (GLushort) CLAMP(src[i], 0, 0xffff);
3887 }
3888 dstRow += dstRowStride;
3889 src += srcWidth * components;
3890 }
3891 }
3892
3893 free((void *) tempImage);
3894 }
3895 return GL_TRUE;
3896 }
3897
3898
3899 /* non-normalized, unsigned int32 */
3900 static GLboolean
3901 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3902 {
3903 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
3904 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3905 const GLint components = _mesa_components_in_format(baseFormat);
3906
3907 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
3908 dstFormat == MESA_FORMAT_RG_UINT32 ||
3909 dstFormat == MESA_FORMAT_RGB_UINT32 ||
3910 dstFormat == MESA_FORMAT_RGBA_UINT32 ||
3911 dstFormat == MESA_FORMAT_ALPHA_UINT32 ||
3912 dstFormat == MESA_FORMAT_INTENSITY_UINT32 ||
3913 dstFormat == MESA_FORMAT_LUMINANCE_UINT32 ||
3914 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_UINT32);
3915 ASSERT(baseInternalFormat == GL_RGBA ||
3916 baseInternalFormat == GL_RGB ||
3917 baseInternalFormat == GL_ALPHA ||
3918 baseInternalFormat == GL_LUMINANCE ||
3919 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3920 baseInternalFormat == GL_INTENSITY);
3921 ASSERT(texelBytes == components * sizeof(GLuint));
3922
3923 /* Note: Pixel transfer ops (scale, bias, table lookup) do not apply
3924 * to integer formats.
3925 */
3926 if (!srcPacking->SwapBytes &&
3927 baseInternalFormat == srcFormat &&
3928 srcType == GL_UNSIGNED_INT) {
3929 /* simple memcpy path */
3930 memcpy_texture(ctx, dims,
3931 dstFormat, dstXoffset, dstYoffset, dstZoffset,
3932 dstRowStride, dstSlices,
3933 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3934 srcAddr, srcPacking);
3935 }
3936 else {
3937 /* general path */
3938 const GLuint *tempImage =
3939 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3940 srcWidth, srcHeight, srcDepth,
3941 srcFormat, srcType, srcAddr, srcPacking);
3942 const GLuint *src = tempImage;
3943 GLint img, row;
3944 if (!tempImage)
3945 return GL_FALSE;
3946 for (img = 0; img < srcDepth; img++) {
3947 GLubyte *dstRow = dstSlices[dstZoffset + img]
3948 + dstYoffset * dstRowStride
3949 + dstXoffset * texelBytes;
3950 for (row = 0; row < srcHeight; row++) {
3951 GLuint *dstTexel = (GLuint *) dstRow;
3952 GLint i;
3953 for (i = 0; i < srcWidth * components; i++) {
3954 dstTexel[i] = src[i];
3955 }
3956 dstRow += dstRowStride;
3957 src += srcWidth * components;
3958 }
3959 }
3960
3961 free((void *) tempImage);
3962 }
3963 return GL_TRUE;
3964 }
3965
3966
3967
3968
3969 #if FEATURE_EXT_texture_sRGB
3970 static GLboolean
3971 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3972 {
3973 gl_format newDstFormat;
3974 GLboolean k;
3975
3976 ASSERT(dstFormat == MESA_FORMAT_SRGB8);
3977
3978 /* reuse normal rgb texstore code */
3979 newDstFormat = MESA_FORMAT_RGB888;
3980
3981 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3982 newDstFormat,
3983 dstXoffset, dstYoffset, dstZoffset,
3984 dstRowStride, dstSlices,
3985 srcWidth, srcHeight, srcDepth,
3986 srcFormat, srcType,
3987 srcAddr, srcPacking);
3988 return k;
3989 }
3990
3991
3992 static GLboolean
3993 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
3994 {
3995 gl_format newDstFormat;
3996 GLboolean k;
3997
3998 ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
3999
4000 /* reuse normal rgba texstore code */
4001 newDstFormat = MESA_FORMAT_RGBA8888;
4002 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
4003 newDstFormat,
4004 dstXoffset, dstYoffset, dstZoffset,
4005 dstRowStride, dstSlices,
4006 srcWidth, srcHeight, srcDepth,
4007 srcFormat, srcType,
4008 srcAddr, srcPacking);
4009 return k;
4010 }
4011
4012
4013 static GLboolean
4014 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
4015 {
4016 gl_format newDstFormat;
4017 GLboolean k;
4018
4019 ASSERT(dstFormat == MESA_FORMAT_SARGB8);
4020
4021 /* reuse normal rgba texstore code */
4022 newDstFormat = MESA_FORMAT_ARGB8888;
4023
4024 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
4025 newDstFormat,
4026 dstXoffset, dstYoffset, dstZoffset,
4027 dstRowStride, dstSlices,
4028 srcWidth, srcHeight, srcDepth,
4029 srcFormat, srcType,
4030 srcAddr, srcPacking);
4031 return k;
4032 }
4033
4034
4035 static GLboolean
4036 _mesa_texstore_sl8(TEXSTORE_PARAMS)
4037 {
4038 gl_format newDstFormat;
4039 GLboolean k;
4040
4041 ASSERT(dstFormat == MESA_FORMAT_SL8);
4042
4043 newDstFormat = MESA_FORMAT_L8;
4044
4045 /* _mesa_textore_a8 handles luminance8 too */
4046 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
4047 newDstFormat,
4048 dstXoffset, dstYoffset, dstZoffset,
4049 dstRowStride, dstSlices,
4050 srcWidth, srcHeight, srcDepth,
4051 srcFormat, srcType,
4052 srcAddr, srcPacking);
4053 return k;
4054 }
4055
4056
4057 static GLboolean
4058 _mesa_texstore_sla8(TEXSTORE_PARAMS)
4059 {
4060 gl_format newDstFormat;
4061 GLboolean k;
4062
4063 ASSERT(dstFormat == MESA_FORMAT_SLA8);
4064
4065 /* reuse normal luminance/alpha texstore code */
4066 newDstFormat = MESA_FORMAT_AL88;
4067
4068 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
4069 newDstFormat,
4070 dstXoffset, dstYoffset, dstZoffset,
4071 dstRowStride, dstSlices,
4072 srcWidth, srcHeight, srcDepth,
4073 srcFormat, srcType,
4074 srcAddr, srcPacking);
4075 return k;
4076 }
4077
4078 #else
4079
4080 /* these are used only in texstore_funcs[] below */
4081 #define _mesa_texstore_srgb8 NULL
4082 #define _mesa_texstore_srgba8 NULL
4083 #define _mesa_texstore_sargb8 NULL
4084 #define _mesa_texstore_sl8 NULL
4085 #define _mesa_texstore_sla8 NULL
4086
4087 #endif /* FEATURE_EXT_texture_sRGB */
4088
4089 static GLboolean
4090 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
4091 {
4092 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4093
4094 ASSERT(dstFormat == MESA_FORMAT_RGB9_E5_FLOAT);
4095 ASSERT(baseInternalFormat == GL_RGB);
4096
4097 if (!ctx->_ImageTransferState &&
4098 !srcPacking->SwapBytes &&
4099 srcFormat == GL_RGB &&
4100 srcType == GL_UNSIGNED_INT_5_9_9_9_REV) {
4101 /* simple memcpy path */
4102 memcpy_texture(ctx, dims,
4103 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4104 dstRowStride, dstSlices,
4105 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4106 srcAddr, srcPacking);
4107 }
4108 else {
4109 /* general path */
4110 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
4111 baseInternalFormat,
4112 baseFormat,
4113 srcWidth, srcHeight, srcDepth,
4114 srcFormat, srcType, srcAddr,
4115 srcPacking,
4116 ctx->_ImageTransferState);
4117 const GLfloat *srcRow = tempImage;
4118 GLint img, row, col;
4119 if (!tempImage)
4120 return GL_FALSE;
4121 for (img = 0; img < srcDepth; img++) {
4122 GLubyte *dstRow = dstSlices[dstZoffset + img]
4123 + dstYoffset * dstRowStride
4124 + dstXoffset * 4;
4125 for (row = 0; row < srcHeight; row++) {
4126 GLuint *dstUI = (GLuint*)dstRow;
4127 for (col = 0; col < srcWidth; col++) {
4128 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
4129 }
4130 dstRow += dstRowStride;
4131 srcRow += srcWidth * 3;
4132 }
4133 }
4134
4135 free((void *) tempImage);
4136 }
4137 return GL_TRUE;
4138 }
4139
4140 static GLboolean
4141 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
4142 {
4143 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4144
4145 ASSERT(dstFormat == MESA_FORMAT_R11_G11_B10_FLOAT);
4146 ASSERT(baseInternalFormat == GL_RGB);
4147
4148 if (!ctx->_ImageTransferState &&
4149 !srcPacking->SwapBytes &&
4150 srcFormat == GL_RGB &&
4151 srcType == GL_UNSIGNED_INT_10F_11F_11F_REV) {
4152 /* simple memcpy path */
4153 memcpy_texture(ctx, dims,
4154 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4155 dstRowStride, dstSlices,
4156 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4157 srcAddr, srcPacking);
4158 }
4159 else {
4160 /* general path */
4161 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
4162 baseInternalFormat,
4163 baseFormat,
4164 srcWidth, srcHeight, srcDepth,
4165 srcFormat, srcType, srcAddr,
4166 srcPacking,
4167 ctx->_ImageTransferState);
4168 const GLfloat *srcRow = tempImage;
4169 GLint img, row, col;
4170 if (!tempImage)
4171 return GL_FALSE;
4172 for (img = 0; img < srcDepth; img++) {
4173 GLubyte *dstRow = dstSlices[dstZoffset + img]
4174 + dstYoffset * dstRowStride
4175 + dstXoffset * 4;
4176 for (row = 0; row < srcHeight; row++) {
4177 GLuint *dstUI = (GLuint*)dstRow;
4178 for (col = 0; col < srcWidth; col++) {
4179 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
4180 }
4181 dstRow += dstRowStride;
4182 srcRow += srcWidth * 3;
4183 }
4184 }
4185
4186 free((void *) tempImage);
4187 }
4188 return GL_TRUE;
4189 }
4190
4191
4192 static GLboolean
4193 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
4194 {
4195 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_X24S8);
4196 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
4197 srcFormat == GL_DEPTH_COMPONENT ||
4198 srcFormat == GL_STENCIL_INDEX);
4199 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
4200 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
4201
4202 if (srcFormat == GL_DEPTH_STENCIL &&
4203 ctx->Pixel.DepthScale == 1.0f &&
4204 ctx->Pixel.DepthBias == 0.0f &&
4205 !srcPacking->SwapBytes) {
4206 /* simple path */
4207 memcpy_texture(ctx, dims,
4208 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4209 dstRowStride, dstSlices,
4210 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4211 srcAddr, srcPacking);
4212 }
4213 else if (srcFormat == GL_DEPTH_COMPONENT ||
4214 srcFormat == GL_STENCIL_INDEX) {
4215 GLint img, row;
4216 const GLint srcRowStride
4217 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
4218 / sizeof(uint64_t);
4219
4220 /* In case we only upload depth we need to preserve the stencil */
4221 for (img = 0; img < srcDepth; img++) {
4222 uint64_t *dstRow = (uint64_t *) (dstSlices[dstZoffset + img]
4223 + dstYoffset * dstRowStride
4224 + dstXoffset * 8);
4225 const uint64_t *src
4226 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
4227 srcWidth, srcHeight,
4228 srcFormat, srcType,
4229 img, 0, 0);
4230 for (row = 0; row < srcHeight; row++) {
4231 /* The unpack functions with:
4232 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
4233 * only write their own dword, so the other dword (stencil
4234 * or depth) is preserved. */
4235 if (srcFormat != GL_STENCIL_INDEX)
4236 _mesa_unpack_depth_span(ctx, srcWidth,
4237 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
4238 dstRow, /* dst addr */
4239 1.0f, srcType, src, srcPacking);
4240
4241 if (srcFormat != GL_DEPTH_COMPONENT)
4242 _mesa_unpack_stencil_span(ctx, srcWidth,
4243 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
4244 dstRow, /* dst addr */
4245 srcType, src, srcPacking,
4246 ctx->_ImageTransferState);
4247
4248 src += srcRowStride;
4249 dstRow += dstRowStride / sizeof(uint64_t);
4250 }
4251 }
4252 }
4253 return GL_TRUE;
4254 }
4255
4256 static GLboolean
4257 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
4258 {
4259 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
4260 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
4261
4262 ASSERT(dstFormat == MESA_FORMAT_ARGB2101010_UINT);
4263 ASSERT(texelBytes == 4);
4264
4265 if (!srcPacking->SwapBytes &&
4266 dstFormat == MESA_FORMAT_ARGB2101010_UINT &&
4267 srcFormat == GL_BGRA_INTEGER_EXT &&
4268 srcType == GL_UNSIGNED_INT_2_10_10_10_REV &&
4269 baseInternalFormat == GL_RGBA) {
4270 /* simple memcpy path */
4271 memcpy_texture(ctx, dims,
4272 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4273 dstRowStride, dstSlices,
4274 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
4275 srcAddr, srcPacking);
4276 }
4277 else {
4278 /* general path */
4279 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
4280 baseInternalFormat,
4281 baseFormat,
4282 srcWidth, srcHeight,
4283 srcDepth, srcFormat,
4284 srcType, srcAddr,
4285 srcPacking);
4286 const GLuint *src = tempImage;
4287 GLint img, row, col;
4288 if (!tempImage)
4289 return GL_FALSE;
4290 for (img = 0; img < srcDepth; img++) {
4291 GLubyte *dstRow = dstSlices[dstZoffset + img]
4292 + dstYoffset * dstRowStride
4293 + dstXoffset * texelBytes;
4294
4295 for (row = 0; row < srcHeight; row++) {
4296 GLuint *dstUI = (GLuint *) dstRow;
4297 for (col = 0; col < srcWidth; col++) {
4298 GLushort a,r,g,b;
4299 r = src[RCOMP];
4300 g = src[GCOMP];
4301 b = src[BCOMP];
4302 a = src[ACOMP];
4303 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
4304 src += 4;
4305 }
4306 dstRow += dstRowStride;
4307 }
4308 }
4309 free((void *) tempImage);
4310 }
4311 return GL_TRUE;
4312 }
4313
4314 static GLboolean
4315 _mesa_texstore_null(TEXSTORE_PARAMS)
4316 {
4317 (void) ctx; (void) dims;
4318 (void) baseInternalFormat;
4319 (void) dstFormat;
4320 (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
4321 (void) dstRowStride; (void) dstSlices,
4322 (void) srcWidth; (void) srcHeight; (void) srcDepth;
4323 (void) srcFormat; (void) srcType;
4324 (void) srcAddr;
4325 (void) srcPacking;
4326
4327 /* should never happen */
4328 _mesa_problem(NULL, "_mesa_texstore_null() is called");
4329 return GL_FALSE;
4330 }
4331
4332
4333 /**
4334 * Return the StoreTexImageFunc pointer to store an image in the given format.
4335 */
4336 static StoreTexImageFunc
4337 _mesa_get_texstore_func(gl_format format)
4338 {
4339 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
4340 static GLboolean initialized = GL_FALSE;
4341
4342 if (!initialized) {
4343 table[MESA_FORMAT_NONE] = _mesa_texstore_null;
4344
4345 table[MESA_FORMAT_RGBA8888] = _mesa_texstore_rgba8888;
4346 table[MESA_FORMAT_RGBA8888_REV] = _mesa_texstore_rgba8888;
4347 table[MESA_FORMAT_ARGB8888] = _mesa_texstore_argb8888;
4348 table[MESA_FORMAT_ARGB8888_REV] = _mesa_texstore_argb8888;
4349 table[MESA_FORMAT_RGBX8888] = _mesa_texstore_rgba8888;
4350 table[MESA_FORMAT_RGBX8888_REV] = _mesa_texstore_rgba8888;
4351 table[MESA_FORMAT_XRGB8888] = _mesa_texstore_argb8888;
4352 table[MESA_FORMAT_XRGB8888_REV] = _mesa_texstore_argb8888;
4353 table[MESA_FORMAT_RGB888] = _mesa_texstore_rgb888;
4354 table[MESA_FORMAT_BGR888] = _mesa_texstore_bgr888;
4355 table[MESA_FORMAT_RGB565] = _mesa_texstore_rgb565;
4356 table[MESA_FORMAT_RGB565_REV] = _mesa_texstore_rgb565;
4357 table[MESA_FORMAT_ARGB4444] = _mesa_texstore_argb4444;
4358 table[MESA_FORMAT_ARGB4444_REV] = _mesa_texstore_argb4444;
4359 table[MESA_FORMAT_RGBA5551] = _mesa_texstore_rgba5551;
4360 table[MESA_FORMAT_ARGB1555] = _mesa_texstore_argb1555;
4361 table[MESA_FORMAT_ARGB1555_REV] = _mesa_texstore_argb1555;
4362 table[MESA_FORMAT_AL44] = _mesa_texstore_unorm44;
4363 table[MESA_FORMAT_AL88] = _mesa_texstore_unorm88;
4364 table[MESA_FORMAT_AL88_REV] = _mesa_texstore_unorm88;
4365 table[MESA_FORMAT_AL1616] = _mesa_texstore_unorm1616;
4366 table[MESA_FORMAT_AL1616_REV] = _mesa_texstore_unorm1616;
4367 table[MESA_FORMAT_RGB332] = _mesa_texstore_rgb332;
4368 table[MESA_FORMAT_A8] = _mesa_texstore_unorm8;
4369 table[MESA_FORMAT_A16] = _mesa_texstore_unorm16;
4370 table[MESA_FORMAT_L8] = _mesa_texstore_unorm8;
4371 table[MESA_FORMAT_L16] = _mesa_texstore_unorm16;
4372 table[MESA_FORMAT_I8] = _mesa_texstore_unorm8;
4373 table[MESA_FORMAT_I16] = _mesa_texstore_unorm16;
4374 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
4375 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
4376 table[MESA_FORMAT_R8] = _mesa_texstore_unorm8;
4377 table[MESA_FORMAT_RG88] = _mesa_texstore_unorm88;
4378 table[MESA_FORMAT_RG88_REV] = _mesa_texstore_unorm88;
4379 table[MESA_FORMAT_R16] = _mesa_texstore_unorm16;
4380 table[MESA_FORMAT_RG1616] = _mesa_texstore_unorm1616;
4381 table[MESA_FORMAT_RG1616_REV] = _mesa_texstore_unorm1616;
4382 table[MESA_FORMAT_ARGB2101010] = _mesa_texstore_argb2101010;
4383 table[MESA_FORMAT_Z24_S8] = _mesa_texstore_z24_s8;
4384 table[MESA_FORMAT_S8_Z24] = _mesa_texstore_s8_z24;
4385 table[MESA_FORMAT_Z16] = _mesa_texstore_z16;
4386 table[MESA_FORMAT_X8_Z24] = _mesa_texstore_x8_z24;
4387 table[MESA_FORMAT_Z24_X8] = _mesa_texstore_z24_x8;
4388 table[MESA_FORMAT_Z32] = _mesa_texstore_z32;
4389 table[MESA_FORMAT_S8] = _mesa_texstore_s8;
4390 table[MESA_FORMAT_SRGB8] = _mesa_texstore_srgb8;
4391 table[MESA_FORMAT_SRGBA8] = _mesa_texstore_srgba8;
4392 table[MESA_FORMAT_SARGB8] = _mesa_texstore_sargb8;
4393 table[MESA_FORMAT_SL8] = _mesa_texstore_sl8;
4394 table[MESA_FORMAT_SLA8] = _mesa_texstore_sla8;
4395 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
4396 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4397 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4398 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4399 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
4400 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
4401 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
4402 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
4403 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
4404 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
4405 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
4406 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
4407 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
4408 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
4409 table[MESA_FORMAT_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4410 table[MESA_FORMAT_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4411 table[MESA_FORMAT_LUMINANCE_FLOAT32] = _mesa_texstore_rgba_float32;
4412 table[MESA_FORMAT_LUMINANCE_FLOAT16] = _mesa_texstore_rgba_float16;
4413 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32] = _mesa_texstore_rgba_float32;
4414 table[MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16] = _mesa_texstore_rgba_float16;
4415 table[MESA_FORMAT_INTENSITY_FLOAT32] = _mesa_texstore_rgba_float32;
4416 table[MESA_FORMAT_INTENSITY_FLOAT16] = _mesa_texstore_rgba_float16;
4417 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
4418 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
4419 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
4420 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
4421 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
4422 table[MESA_FORMAT_SIGNED_R8] = _mesa_texstore_snorm8;
4423 table[MESA_FORMAT_SIGNED_RG88_REV] = _mesa_texstore_snorm88;
4424 table[MESA_FORMAT_SIGNED_RGBX8888] = _mesa_texstore_signed_rgbx8888;
4425 table[MESA_FORMAT_SIGNED_RGBA8888] = _mesa_texstore_signed_rgba8888;
4426 table[MESA_FORMAT_SIGNED_RGBA8888_REV] = _mesa_texstore_signed_rgba8888;
4427 table[MESA_FORMAT_SIGNED_R16] = _mesa_texstore_snorm16;
4428 table[MESA_FORMAT_SIGNED_GR1616] = _mesa_texstore_snorm1616;
4429 table[MESA_FORMAT_SIGNED_RGB_16] = _mesa_texstore_signed_rgba_16;
4430 table[MESA_FORMAT_SIGNED_RGBA_16] = _mesa_texstore_signed_rgba_16;
4431 table[MESA_FORMAT_RGBA_16] = _mesa_texstore_rgba_16;
4432 table[MESA_FORMAT_RED_RGTC1] = _mesa_texstore_red_rgtc1;
4433 table[MESA_FORMAT_SIGNED_RED_RGTC1] = _mesa_texstore_signed_red_rgtc1;
4434 table[MESA_FORMAT_RG_RGTC2] = _mesa_texstore_rg_rgtc2;
4435 table[MESA_FORMAT_SIGNED_RG_RGTC2] = _mesa_texstore_signed_rg_rgtc2;
4436 table[MESA_FORMAT_L_LATC1] = _mesa_texstore_red_rgtc1;
4437 table[MESA_FORMAT_SIGNED_L_LATC1] = _mesa_texstore_signed_red_rgtc1;
4438 table[MESA_FORMAT_LA_LATC2] = _mesa_texstore_rg_rgtc2;
4439 table[MESA_FORMAT_SIGNED_LA_LATC2] = _mesa_texstore_signed_rg_rgtc2;
4440 table[MESA_FORMAT_SIGNED_A8] = _mesa_texstore_snorm8;
4441 table[MESA_FORMAT_SIGNED_L8] = _mesa_texstore_snorm8;
4442 table[MESA_FORMAT_SIGNED_AL88] = _mesa_texstore_snorm88;
4443 table[MESA_FORMAT_SIGNED_I8] = _mesa_texstore_snorm8;
4444 table[MESA_FORMAT_SIGNED_A16] = _mesa_texstore_snorm16;
4445 table[MESA_FORMAT_SIGNED_L16] = _mesa_texstore_snorm16;
4446 table[MESA_FORMAT_SIGNED_AL1616] = _mesa_texstore_snorm1616;
4447 table[MESA_FORMAT_SIGNED_I16] = _mesa_texstore_snorm16;
4448 table[MESA_FORMAT_RGB9_E5_FLOAT] = _mesa_texstore_rgb9_e5;
4449 table[MESA_FORMAT_R11_G11_B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
4450 table[MESA_FORMAT_Z32_FLOAT] = _mesa_texstore_z32;
4451 table[MESA_FORMAT_Z32_FLOAT_X24S8] = _mesa_texstore_z32f_x24s8;
4452
4453 table[MESA_FORMAT_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4454 table[MESA_FORMAT_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4455 table[MESA_FORMAT_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4456 table[MESA_FORMAT_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4457 table[MESA_FORMAT_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4458 table[MESA_FORMAT_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4459
4460 table[MESA_FORMAT_INTENSITY_UINT8] = _mesa_texstore_rgba_uint8;
4461 table[MESA_FORMAT_INTENSITY_UINT16] = _mesa_texstore_rgba_uint16;
4462 table[MESA_FORMAT_INTENSITY_UINT32] = _mesa_texstore_rgba_uint32;
4463 table[MESA_FORMAT_INTENSITY_INT8] = _mesa_texstore_rgba_int8;
4464 table[MESA_FORMAT_INTENSITY_INT16] = _mesa_texstore_rgba_int16;
4465 table[MESA_FORMAT_INTENSITY_INT32] = _mesa_texstore_rgba_int32;
4466
4467 table[MESA_FORMAT_LUMINANCE_UINT8] = _mesa_texstore_rgba_uint8;
4468 table[MESA_FORMAT_LUMINANCE_UINT16] = _mesa_texstore_rgba_uint16;
4469 table[MESA_FORMAT_LUMINANCE_UINT32] = _mesa_texstore_rgba_uint32;
4470 table[MESA_FORMAT_LUMINANCE_INT8] = _mesa_texstore_rgba_int8;
4471 table[MESA_FORMAT_LUMINANCE_INT16] = _mesa_texstore_rgba_int16;
4472 table[MESA_FORMAT_LUMINANCE_INT32] = _mesa_texstore_rgba_int32;
4473
4474 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT8] = _mesa_texstore_rgba_uint8;
4475 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT16] = _mesa_texstore_rgba_uint16;
4476 table[MESA_FORMAT_LUMINANCE_ALPHA_UINT32] = _mesa_texstore_rgba_uint32;
4477 table[MESA_FORMAT_LUMINANCE_ALPHA_INT8] = _mesa_texstore_rgba_int8;
4478 table[MESA_FORMAT_LUMINANCE_ALPHA_INT16] = _mesa_texstore_rgba_int16;
4479 table[MESA_FORMAT_LUMINANCE_ALPHA_INT32] = _mesa_texstore_rgba_int32;
4480
4481 table[MESA_FORMAT_R_INT8] = _mesa_texstore_rgba_int8;
4482 table[MESA_FORMAT_RG_INT8] = _mesa_texstore_rgba_int8;
4483 table[MESA_FORMAT_RGB_INT8] = _mesa_texstore_rgba_int8;
4484 table[MESA_FORMAT_RGBA_INT8] = _mesa_texstore_rgba_int8;
4485 table[MESA_FORMAT_R_INT16] = _mesa_texstore_rgba_int16;
4486 table[MESA_FORMAT_RG_INT16] = _mesa_texstore_rgba_int16;
4487 table[MESA_FORMAT_RGB_INT16] = _mesa_texstore_rgba_int16;
4488 table[MESA_FORMAT_RGBA_INT16] = _mesa_texstore_rgba_int16;
4489 table[MESA_FORMAT_R_INT32] = _mesa_texstore_rgba_int32;
4490 table[MESA_FORMAT_RG_INT32] = _mesa_texstore_rgba_int32;
4491 table[MESA_FORMAT_RGB_INT32] = _mesa_texstore_rgba_int32;
4492 table[MESA_FORMAT_RGBA_INT32] = _mesa_texstore_rgba_int32;
4493
4494 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
4495 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
4496 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
4497 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
4498 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
4499 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
4500 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
4501 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
4502 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
4503 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
4504 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
4505 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
4506
4507 table[MESA_FORMAT_ARGB2101010_UINT] = _mesa_texstore_argb2101010_uint;
4508 initialized = GL_TRUE;
4509 }
4510
4511 ASSERT(table[format]);
4512 return table[format];
4513 }
4514
4515
4516 /**
4517 * Store user data into texture memory.
4518 * Called via glTex[Sub]Image1/2/3D()
4519 */
4520 GLboolean
4521 _mesa_texstore(TEXSTORE_PARAMS)
4522 {
4523 StoreTexImageFunc storeImage;
4524 GLboolean success;
4525
4526 storeImage = _mesa_get_texstore_func(dstFormat);
4527
4528 success = storeImage(ctx, dims, baseInternalFormat,
4529 dstFormat, dstXoffset, dstYoffset, dstZoffset,
4530 dstRowStride, dstSlices,
4531 srcWidth, srcHeight, srcDepth,
4532 srcFormat, srcType, srcAddr, srcPacking);
4533 return success;
4534 }
4535
4536
4537 /**
4538 * Normally, we'll only _write_ texel data to a texture when we map it.
4539 * But if the user is providing depth or stencil values and the texture
4540 * image is a combined depth/stencil format, we'll actually read from
4541 * the texture buffer too (in order to insert the depth or stencil values.
4542 * \param userFormat the user-provided image format
4543 * \param texFormat the destination texture format
4544 */
4545 static GLbitfield
4546 get_read_write_mode(GLenum userFormat, gl_format texFormat)
4547 {
4548 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
4549 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
4550 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
4551 else
4552 return GL_MAP_WRITE_BIT;
4553 }
4554
4555 /**
4556 * This is the software fallback for Driver.TexImage1D().
4557 * \sa _mesa_store_teximage2d()
4558 */
4559 void
4560 _mesa_store_teximage1d(struct gl_context *ctx, GLenum target, GLint level,
4561 GLint internalFormat,
4562 GLint width, GLint border,
4563 GLenum format, GLenum type, const GLvoid *pixels,
4564 const struct gl_pixelstore_attrib *packing,
4565 struct gl_texture_object *texObj,
4566 struct gl_texture_image *texImage)
4567 {
4568 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4569 GLubyte *dstMap;
4570 GLint dstRowStride;
4571 GLboolean success;
4572
4573 (void) border;
4574
4575 if (width == 0)
4576 return;
4577
4578 /* allocate storage for texture data */
4579 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4580 width, 1, 1)) {
4581 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4582 return;
4583 }
4584
4585 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4586 pixels, packing, "glTexImage1D");
4587 if (!pixels) {
4588 /* Note: we check for a NULL image pointer here, _after_ we allocated
4589 * memory for the texture. That's what the GL spec calls for.
4590 */
4591 return;
4592 }
4593
4594 /* Map dest texture buffer (write to whole region) */
4595 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4596 0, 0, width, 1,
4597 rwMode,
4598 &dstMap, &dstRowStride);
4599
4600 success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4601 texImage->TexFormat,
4602 0, 0, 0, /* dstX/Y/Zoffset */
4603 0, /* dstRowStride */
4604 &dstMap,
4605 width, 1, 1,
4606 format, type, pixels, packing);
4607
4608 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4609
4610 if (!success)
4611 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
4612
4613 _mesa_unmap_teximage_pbo(ctx, packing);
4614 }
4615
4616
4617 /**
4618 * This is the software fallback for Driver.TexImage2D().
4619 *
4620 * This function is oriented toward storing images in main memory, rather
4621 * than VRAM. Device driver's can easily plug in their own replacement.
4622 */
4623 void
4624 _mesa_store_teximage2d(struct gl_context *ctx, GLenum target, GLint level,
4625 GLint internalFormat,
4626 GLint width, GLint height, GLint border,
4627 GLenum format, GLenum type, const void *pixels,
4628 const struct gl_pixelstore_attrib *packing,
4629 struct gl_texture_object *texObj,
4630 struct gl_texture_image *texImage)
4631 {
4632 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4633 GLubyte *dstMap;
4634 GLint dstRowStride;
4635 GLboolean success;
4636
4637 (void) border;
4638
4639 if (width == 0 || height == 0)
4640 return;
4641
4642 /* allocate storage for texture data */
4643 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4644 width, height, 1)) {
4645 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4646 return;
4647 }
4648
4649 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4650 pixels, packing, "glTexImage2D");
4651 if (!pixels) {
4652 /* Note: we check for a NULL image pointer here, _after_ we allocated
4653 * memory for the texture. That's what the GL spec calls for.
4654 */
4655 return;
4656 }
4657
4658 if (target == GL_TEXTURE_1D_ARRAY) {
4659 const GLint srcStride =
4660 _mesa_image_row_stride(packing, width, format, type);
4661 int y;
4662
4663 success = GL_TRUE;
4664
4665 for (y = 0; y < height; y++) {
4666 /* Map dest texture buffer (write to whole region) */
4667 ctx->Driver.MapTextureImage(ctx, texImage, y,
4668 0, 0, width, 1,
4669 rwMode,
4670 &dstMap, &dstRowStride);
4671 assert(dstMap);
4672 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4673 texImage->TexFormat,
4674 0, 0, 0, /* dstX/Y/Zoffset */
4675 dstRowStride,
4676 &dstMap,
4677 width, 1, 1,
4678 format, type, pixels, packing);
4679 ctx->Driver.UnmapTextureImage(ctx, texImage, y);
4680
4681 if (!success)
4682 break;
4683
4684 pixels = (const GLubyte *) pixels + srcStride;
4685 }
4686 } else {
4687 /* Map dest texture buffer (write to whole region) */
4688 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4689 0, 0, width, height,
4690 rwMode,
4691 &dstMap, &dstRowStride);
4692 assert(dstMap);
4693 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4694 texImage->TexFormat,
4695 0, 0, 0, /* dstX/Y/Zoffset */
4696 dstRowStride,
4697 &dstMap,
4698 width, height, 1,
4699 format, type, pixels, packing);
4700
4701 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4702 }
4703
4704 if (!success)
4705 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
4706
4707 _mesa_unmap_teximage_pbo(ctx, packing);
4708 }
4709
4710
4711
4712 /**
4713 * This is the software fallback for Driver.TexImage3D().
4714 * \sa _mesa_store_teximage2d()
4715 */
4716 void
4717 _mesa_store_teximage3d(struct gl_context *ctx, GLenum target, GLint level,
4718 GLint internalFormat,
4719 GLint width, GLint height, GLint depth, GLint border,
4720 GLenum format, GLenum type, const void *pixels,
4721 const struct gl_pixelstore_attrib *packing,
4722 struct gl_texture_object *texObj,
4723 struct gl_texture_image *texImage)
4724 {
4725 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4726 GLboolean success;
4727 GLint slice;
4728 GLubyte **sliceMaps;
4729 GLint dstRowStride;
4730
4731 (void) border;
4732
4733 if (width == 0 || height == 0 || depth == 0)
4734 return;
4735
4736 /* allocate storage for texture data */
4737 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4738 width, height, depth)) {
4739 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4740 return;
4741 }
4742
4743 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth,
4744 format, type,
4745 pixels, packing, "glTexImage3D");
4746 if (!pixels) {
4747 /* Note: we check for a NULL image pointer here, _after_ we allocated
4748 * memory for the texture. That's what the GL spec calls for.
4749 */
4750 return;
4751 }
4752
4753 if (target == GL_TEXTURE_1D_ARRAY) {
4754 depth = height;
4755 height = 1;
4756 }
4757
4758 sliceMaps = (GLubyte **) malloc(depth * sizeof(GLubyte *));
4759
4760 /* Map dest texture buffer slices */
4761 for (slice = 0; slice < depth; slice++) {
4762 ctx->Driver.MapTextureImage(ctx, texImage, slice,
4763 0, 0, width, height,
4764 rwMode,
4765 &sliceMaps[slice], &dstRowStride);
4766 }
4767
4768 success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4769 texImage->TexFormat,
4770 0, 0, 0, /* dstX/Y/Zoffset */
4771 dstRowStride,
4772 sliceMaps,
4773 width, height, depth,
4774 format, type, pixels, packing);
4775
4776 /* Unmap dest texture buffer slices */
4777 for (slice = 0; slice < depth; slice++) {
4778 ctx->Driver.UnmapTextureImage(ctx, texImage, slice);
4779 }
4780
4781 if (!success)
4782 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
4783
4784 _mesa_unmap_teximage_pbo(ctx, packing);
4785
4786 free(sliceMaps);
4787 }
4788
4789
4790
4791
4792 /*
4793 * This is the software fallback for Driver.TexSubImage1D()
4794 * and Driver.CopyTexSubImage1D().
4795 */
4796 void
4797 _mesa_store_texsubimage1d(struct gl_context *ctx, GLenum target, GLint level,
4798 GLint xoffset, GLint width,
4799 GLenum format, GLenum type, const void *pixels,
4800 const struct gl_pixelstore_attrib *packing,
4801 struct gl_texture_object *texObj,
4802 struct gl_texture_image *texImage)
4803 {
4804 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4805 GLubyte *dstMap;
4806 GLint dstRowStride;
4807 GLboolean success;
4808
4809 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4810 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
4811 pixels, packing, "glTexSubImage1D");
4812 if (!pixels)
4813 return;
4814
4815 /* Map dest texture buffer (write to whole region) */
4816 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4817 xoffset, 0, width, 1,
4818 rwMode,
4819 &dstMap, &dstRowStride);
4820
4821 success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
4822 texImage->TexFormat,
4823 0, 0, 0, /* dstX/Y/Zoffset */
4824 dstRowStride,
4825 &dstMap,
4826 width, 1, 1,
4827 format, type, pixels, packing);
4828
4829 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4830
4831 if (!success)
4832 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
4833
4834 _mesa_unmap_teximage_pbo(ctx, packing);
4835 }
4836
4837
4838
4839 /**
4840 * This is the software fallback for Driver.TexSubImage2D()
4841 * and Driver.CopyTexSubImage2D().
4842 */
4843 void
4844 _mesa_store_texsubimage2d(struct gl_context *ctx, GLenum target, GLint level,
4845 GLint xoffset, GLint yoffset,
4846 GLint width, GLint height,
4847 GLenum format, GLenum type, const void *pixels,
4848 const struct gl_pixelstore_attrib *packing,
4849 struct gl_texture_object *texObj,
4850 struct gl_texture_image *texImage)
4851 {
4852 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4853 GLubyte *dstMap;
4854 GLint dstRowStride;
4855 GLboolean success;
4856
4857 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4858 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
4859 pixels, packing, "glTexSubImage2D");
4860 if (!pixels)
4861 return;
4862
4863 /* Map dest texture buffer (write to whole region) */
4864 ctx->Driver.MapTextureImage(ctx, texImage, 0,
4865 xoffset, yoffset, width, height,
4866 rwMode,
4867 &dstMap, &dstRowStride);
4868
4869 success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
4870 texImage->TexFormat,
4871 0, 0, 0, /* dstX/Y/Zoffset */
4872 dstRowStride,
4873 &dstMap,
4874 width, height, 1,
4875 format, type, pixels, packing);
4876
4877 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
4878
4879 if (!success)
4880 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
4881
4882 _mesa_unmap_teximage_pbo(ctx, packing);
4883 }
4884
4885
4886 /*
4887 * This is the software fallback for Driver.TexSubImage3D().
4888 * and Driver.CopyTexSubImage3D().
4889 */
4890 void
4891 _mesa_store_texsubimage3d(struct gl_context *ctx, GLenum target, GLint level,
4892 GLint xoffset, GLint yoffset, GLint zoffset,
4893 GLint width, GLint height, GLint depth,
4894 GLenum format, GLenum type, const void *pixels,
4895 const struct gl_pixelstore_attrib *packing,
4896 struct gl_texture_object *texObj,
4897 struct gl_texture_image *texImage)
4898 {
4899 const GLbitfield rwMode = get_read_write_mode(format, texImage->TexFormat);
4900 GLboolean success;
4901 GLint slice;
4902 GLubyte **sliceMaps;
4903 GLint dstRowStride;
4904
4905 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4906 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
4907 type, pixels, packing,
4908 "glTexSubImage3D");
4909 if (!pixels)
4910 return;
4911
4912 sliceMaps = (GLubyte **) malloc(depth * sizeof(GLubyte *));
4913
4914 /* Map dest texture buffer slices */
4915 for (slice = 0; slice < depth; slice++) {
4916 ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice,
4917 xoffset, yoffset, width, height,
4918 rwMode,
4919 &sliceMaps[slice], &dstRowStride);
4920 }
4921
4922 success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
4923 texImage->TexFormat,
4924 0, 0, 0,
4925 dstRowStride,
4926 sliceMaps,
4927 width, height, depth,
4928 format, type, pixels, packing);
4929
4930 /* Unmap dest texture buffer slices */
4931 for (slice = 0; slice < depth; slice++) {
4932 ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice);
4933 }
4934
4935 if (!success)
4936 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
4937
4938 _mesa_unmap_teximage_pbo(ctx, packing);
4939
4940 free(sliceMaps);
4941 }
4942
4943
4944 /*
4945 * Fallback for Driver.CompressedTexImage1D()
4946 */
4947 void
4948 _mesa_store_compressed_teximage1d(struct gl_context *ctx,
4949 GLenum target, GLint level,
4950 GLint internalFormat,
4951 GLint width, GLint border,
4952 GLsizei imageSize, const GLvoid *data,
4953 struct gl_texture_object *texObj,
4954 struct gl_texture_image *texImage)
4955 {
4956 /* this space intentionally left blank */
4957 (void) ctx;
4958 (void) target; (void) level;
4959 (void) internalFormat;
4960 (void) width; (void) border;
4961 (void) imageSize; (void) data;
4962 (void) texObj;
4963 (void) texImage;
4964 }
4965
4966
4967
4968 /**
4969 * Fallback for Driver.CompressedTexImage2D()
4970 */
4971 void
4972 _mesa_store_compressed_teximage2d(struct gl_context *ctx,
4973 GLenum target, GLint level,
4974 GLint internalFormat,
4975 GLint width, GLint height, GLint border,
4976 GLsizei imageSize, const GLvoid *data,
4977 struct gl_texture_object *texObj,
4978 struct gl_texture_image *texImage)
4979 {
4980 GLubyte *dstMap;
4981 GLint dstRowStride;
4982
4983 /* This is pretty simple, basically just do a memcpy without worrying
4984 * about the usual image unpacking or image transfer operations.
4985 */
4986 ASSERT(texObj);
4987 ASSERT(texImage);
4988 ASSERT(texImage->Width > 0);
4989 ASSERT(texImage->Height > 0);
4990 ASSERT(texImage->Depth == 1);
4991
4992 /* allocate storage for texture data */
4993 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage, texImage->TexFormat,
4994 width, height, 1)) {
4995 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
4996 return;
4997 }
4998
4999 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
5000 &ctx->Unpack,
5001 "glCompressedTexImage2D");
5002 if (!data)
5003 return;
5004
5005
5006 /* Map dest texture buffer (write to whole region) */
5007 ctx->Driver.MapTextureImage(ctx, texImage, 0,
5008 0, 0, width, height,
5009 GL_MAP_WRITE_BIT,
5010 &dstMap, &dstRowStride);
5011
5012 /* copy the data */
5013 memcpy(dstMap, data, imageSize);
5014
5015 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
5016
5017 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
5018 }
5019
5020
5021
5022 /*
5023 * Fallback for Driver.CompressedTexImage3D()
5024 */
5025 void
5026 _mesa_store_compressed_teximage3d(struct gl_context *ctx,
5027 GLenum target, GLint level,
5028 GLint internalFormat,
5029 GLint width, GLint height, GLint depth,
5030 GLint border,
5031 GLsizei imageSize, const GLvoid *data,
5032 struct gl_texture_object *texObj,
5033 struct gl_texture_image *texImage)
5034 {
5035 /* this space intentionally left blank */
5036 (void) ctx;
5037 (void) target; (void) level;
5038 (void) internalFormat;
5039 (void) width; (void) height; (void) depth;
5040 (void) border;
5041 (void) imageSize; (void) data;
5042 (void) texObj;
5043 (void) texImage;
5044 }
5045
5046
5047
5048 /**
5049 * Fallback for Driver.CompressedTexSubImage1D()
5050 */
5051 void
5052 _mesa_store_compressed_texsubimage1d(struct gl_context *ctx, GLenum target,
5053 GLint level,
5054 GLint xoffset, GLsizei width,
5055 GLenum format,
5056 GLsizei imageSize, const GLvoid *data,
5057 struct gl_texture_object *texObj,
5058 struct gl_texture_image *texImage)
5059 {
5060 /* there are no compressed 1D texture formats yet */
5061 (void) ctx;
5062 (void) target; (void) level;
5063 (void) xoffset; (void) width;
5064 (void) format;
5065 (void) imageSize; (void) data;
5066 (void) texObj;
5067 (void) texImage;
5068 }
5069
5070
5071 /**
5072 * Fallback for Driver.CompressedTexSubImage2D()
5073 */
5074 void
5075 _mesa_store_compressed_texsubimage2d(struct gl_context *ctx, GLenum target,
5076 GLint level,
5077 GLint xoffset, GLint yoffset,
5078 GLsizei width, GLsizei height,
5079 GLenum format,
5080 GLsizei imageSize, const GLvoid *data,
5081 struct gl_texture_object *texObj,
5082 struct gl_texture_image *texImage)
5083 {
5084 GLint bytesPerRow, dstRowStride, srcRowStride;
5085 GLint i, rows;
5086 GLubyte *dstMap;
5087 const GLubyte *src;
5088 const gl_format texFormat = texImage->TexFormat;
5089 GLuint bw, bh;
5090
5091 _mesa_get_format_block_size(texFormat, &bw, &bh);
5092
5093 /* these should have been caught sooner */
5094 ASSERT((width % bw) == 0 || width == 2 || width == 1);
5095 ASSERT((height % bh) == 0 || height == 2 || height == 1);
5096 ASSERT((xoffset % bw) == 0);
5097 ASSERT((yoffset % bh) == 0);
5098
5099 /* get pointer to src pixels (may be in a pbo which we'll map here) */
5100 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
5101 &ctx->Unpack,
5102 "glCompressedTexSubImage2D");
5103 if (!data)
5104 return;
5105
5106 srcRowStride = _mesa_format_row_stride(texFormat, width);
5107 src = (const GLubyte *) data;
5108
5109 /* Map dest texture buffer (write to whole region) */
5110 ctx->Driver.MapTextureImage(ctx, texImage, 0,
5111 xoffset, yoffset, width, height,
5112 GL_MAP_WRITE_BIT,
5113 &dstMap, &dstRowStride);
5114
5115 bytesPerRow = srcRowStride; /* bytes per row of blocks */
5116 rows = height / bh; /* rows in blocks */
5117
5118 /* copy rows of blocks */
5119 for (i = 0; i < rows; i++) {
5120 memcpy(dstMap, src, bytesPerRow);
5121 dstMap += dstRowStride;
5122 src += srcRowStride;
5123 }
5124
5125 ctx->Driver.UnmapTextureImage(ctx, texImage, 0);
5126
5127 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
5128 }
5129
5130
5131 /**
5132 * Fallback for Driver.CompressedTexSubImage3D()
5133 */
5134 void
5135 _mesa_store_compressed_texsubimage3d(struct gl_context *ctx, GLenum target,
5136 GLint level,
5137 GLint xoffset, GLint yoffset, GLint zoffset,
5138 GLsizei width, GLsizei height, GLsizei depth,
5139 GLenum format,
5140 GLsizei imageSize, const GLvoid *data,
5141 struct gl_texture_object *texObj,
5142 struct gl_texture_image *texImage)
5143 {
5144 /* there are no compressed 3D texture formats yet */
5145 (void) ctx;
5146 (void) target; (void) level;
5147 (void) xoffset; (void) yoffset; (void) zoffset;
5148 (void) width; (void) height; (void) depth;
5149 (void) format;
5150 (void) imageSize; (void) data;
5151 (void) texObj;
5152 (void) texImage;
5153 }