mesa: Allow setting GL_TEXTURE_MAX_LEVEL to 0 with GL_TEXTURE_RECTANGLE.
[mesa.git] / src / mesa / main / texstore.c
1 /*
2 * Mesa 3-D graphics library
3 *
4 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
5 * Copyright (c) 2008-2009 VMware, Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
23 * 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.TexImage = _mesa_store_teximage;
41 * ctx->Driver.TexSubImage = _mesa_store_texsubimage;
42 * etc...
43 *
44 * Texture image processing is actually kind of complicated. We have to do:
45 * Format/type conversions
46 * pixel unpacking
47 * pixel transfer (scale, bais, lookup, etc)
48 *
49 * These functions can handle most everything, including processing full
50 * images and sub-images.
51 */
52
53
54 #include "glheader.h"
55 #include "bufferobj.h"
56 #include "colormac.h"
57 #include "format_pack.h"
58 #include "image.h"
59 #include "macros.h"
60 #include "mipmap.h"
61 #include "mtypes.h"
62 #include "pack.h"
63 #include "pbo.h"
64 #include "imports.h"
65 #include "texcompress.h"
66 #include "texcompress_fxt1.h"
67 #include "texcompress_rgtc.h"
68 #include "texcompress_s3tc.h"
69 #include "texcompress_etc.h"
70 #include "teximage.h"
71 #include "texstore.h"
72 #include "enums.h"
73 #include "glformats.h"
74 #include "../../gallium/auxiliary/util/u_format_rgb9e5.h"
75 #include "../../gallium/auxiliary/util/u_format_r11g11b10f.h"
76
77
78 enum {
79 ZERO = 4,
80 ONE = 5
81 };
82
83
84 /**
85 * Texture image storage function.
86 */
87 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
88
89
90 /**
91 * Return GL_TRUE if the given image format is one that be converted
92 * to another format by swizzling.
93 */
94 static GLboolean
95 can_swizzle(GLenum logicalBaseFormat)
96 {
97 switch (logicalBaseFormat) {
98 case GL_RGBA:
99 case GL_RGB:
100 case GL_LUMINANCE_ALPHA:
101 case GL_INTENSITY:
102 case GL_ALPHA:
103 case GL_LUMINANCE:
104 case GL_RED:
105 case GL_GREEN:
106 case GL_BLUE:
107 case GL_BGR:
108 case GL_BGRA:
109 case GL_ABGR_EXT:
110 case GL_RG:
111 return GL_TRUE;
112 default:
113 return GL_FALSE;
114 }
115 }
116
117
118
119 enum {
120 IDX_LUMINANCE = 0,
121 IDX_ALPHA,
122 IDX_INTENSITY,
123 IDX_LUMINANCE_ALPHA,
124 IDX_RGB,
125 IDX_RGBA,
126 IDX_RED,
127 IDX_GREEN,
128 IDX_BLUE,
129 IDX_BGR,
130 IDX_BGRA,
131 IDX_ABGR,
132 IDX_RG,
133 MAX_IDX
134 };
135
136 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
137 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
138 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
139 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
140
141
142 static const struct {
143 GLubyte format_idx;
144 GLubyte to_rgba[6];
145 GLubyte from_rgba[6];
146 } mappings[MAX_IDX] =
147 {
148 {
149 IDX_LUMINANCE,
150 MAP4(0,0,0,ONE),
151 MAP1(0)
152 },
153
154 {
155 IDX_ALPHA,
156 MAP4(ZERO, ZERO, ZERO, 0),
157 MAP1(3)
158 },
159
160 {
161 IDX_INTENSITY,
162 MAP4(0, 0, 0, 0),
163 MAP1(0),
164 },
165
166 {
167 IDX_LUMINANCE_ALPHA,
168 MAP4(0,0,0,1),
169 MAP2(0,3)
170 },
171
172 {
173 IDX_RGB,
174 MAP4(0,1,2,ONE),
175 MAP3(0,1,2)
176 },
177
178 {
179 IDX_RGBA,
180 MAP4(0,1,2,3),
181 MAP4(0,1,2,3),
182 },
183
184 {
185 IDX_RED,
186 MAP4(0, ZERO, ZERO, ONE),
187 MAP1(0),
188 },
189
190 {
191 IDX_GREEN,
192 MAP4(ZERO, 0, ZERO, ONE),
193 MAP1(1),
194 },
195
196 {
197 IDX_BLUE,
198 MAP4(ZERO, ZERO, 0, ONE),
199 MAP1(2),
200 },
201
202 {
203 IDX_BGR,
204 MAP4(2,1,0,ONE),
205 MAP3(2,1,0)
206 },
207
208 {
209 IDX_BGRA,
210 MAP4(2,1,0,3),
211 MAP4(2,1,0,3)
212 },
213
214 {
215 IDX_ABGR,
216 MAP4(3,2,1,0),
217 MAP4(3,2,1,0)
218 },
219
220 {
221 IDX_RG,
222 MAP4(0, 1, ZERO, ONE),
223 MAP2(0, 1)
224 },
225 };
226
227
228
229 /**
230 * Convert a GL image format enum to an IDX_* value (see above).
231 */
232 static int
233 get_map_idx(GLenum value)
234 {
235 switch (value) {
236 case GL_LUMINANCE: return IDX_LUMINANCE;
237 case GL_ALPHA: return IDX_ALPHA;
238 case GL_INTENSITY: return IDX_INTENSITY;
239 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
240 case GL_RGB: return IDX_RGB;
241 case GL_RGBA: return IDX_RGBA;
242 case GL_RED: return IDX_RED;
243 case GL_GREEN: return IDX_GREEN;
244 case GL_BLUE: return IDX_BLUE;
245 case GL_BGR: return IDX_BGR;
246 case GL_BGRA: return IDX_BGRA;
247 case GL_ABGR_EXT: return IDX_ABGR;
248 case GL_RG: return IDX_RG;
249 default:
250 _mesa_problem(NULL, "Unexpected inFormat");
251 return 0;
252 }
253 }
254
255
256 /**
257 * When promoting texture formats (see below) we need to compute the
258 * mapping of dest components back to source components.
259 * This function does that.
260 * \param inFormat the incoming format of the texture
261 * \param outFormat the final texture format
262 * \return map[6] a full 6-component map
263 */
264 static void
265 compute_component_mapping(GLenum inFormat, GLenum outFormat,
266 GLubyte *map)
267 {
268 const int inFmt = get_map_idx(inFormat);
269 const int outFmt = get_map_idx(outFormat);
270 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
271 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
272 int i;
273
274 for (i = 0; i < 4; i++)
275 map[i] = in2rgba[rgba2out[i]];
276
277 map[ZERO] = ZERO;
278 map[ONE] = ONE;
279
280 #if 0
281 printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
282 inFormat, _mesa_lookup_enum_by_nr(inFormat),
283 outFormat, _mesa_lookup_enum_by_nr(outFormat),
284 map[0],
285 map[1],
286 map[2],
287 map[3],
288 map[4],
289 map[5]);
290 #endif
291 }
292
293
294 /**
295 * Make a temporary (color) texture image with GLfloat components.
296 * Apply all needed pixel unpacking and pixel transfer operations.
297 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
298 * Suppose the user specifies GL_LUMINANCE as the internal texture format
299 * but the graphics hardware doesn't support luminance textures. So, we might
300 * use an RGB hardware format instead.
301 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
302 *
303 * \param ctx the rendering context
304 * \param dims image dimensions: 1, 2 or 3
305 * \param logicalBaseFormat basic texture derived from the user's
306 * internal texture format value
307 * \param textureBaseFormat the actual basic format of the texture
308 * \param srcWidth source image width
309 * \param srcHeight source image height
310 * \param srcDepth source image depth
311 * \param srcFormat source image format
312 * \param srcType source image type
313 * \param srcAddr source image address
314 * \param srcPacking source image pixel packing
315 * \return resulting image with format = textureBaseFormat and type = GLfloat.
316 */
317 GLfloat *
318 _mesa_make_temp_float_image(struct gl_context *ctx, GLuint dims,
319 GLenum logicalBaseFormat,
320 GLenum textureBaseFormat,
321 GLint srcWidth, GLint srcHeight, GLint srcDepth,
322 GLenum srcFormat, GLenum srcType,
323 const GLvoid *srcAddr,
324 const struct gl_pixelstore_attrib *srcPacking,
325 GLbitfield transferOps)
326 {
327 GLfloat *tempImage;
328 const GLint components = _mesa_components_in_format(logicalBaseFormat);
329 const GLint srcStride =
330 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
331 GLfloat *dst;
332 GLint img, row;
333
334 ASSERT(dims >= 1 && dims <= 3);
335
336 ASSERT(logicalBaseFormat == GL_RGBA ||
337 logicalBaseFormat == GL_RGB ||
338 logicalBaseFormat == GL_RG ||
339 logicalBaseFormat == GL_RED ||
340 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
341 logicalBaseFormat == GL_LUMINANCE ||
342 logicalBaseFormat == GL_ALPHA ||
343 logicalBaseFormat == GL_INTENSITY ||
344 logicalBaseFormat == GL_DEPTH_COMPONENT);
345
346 ASSERT(textureBaseFormat == GL_RGBA ||
347 textureBaseFormat == GL_RGB ||
348 textureBaseFormat == GL_RG ||
349 textureBaseFormat == GL_RED ||
350 textureBaseFormat == GL_LUMINANCE_ALPHA ||
351 textureBaseFormat == GL_LUMINANCE ||
352 textureBaseFormat == GL_ALPHA ||
353 textureBaseFormat == GL_INTENSITY ||
354 textureBaseFormat == GL_DEPTH_COMPONENT);
355
356 tempImage = malloc(srcWidth * srcHeight * srcDepth
357 * components * sizeof(GLfloat));
358 if (!tempImage)
359 return NULL;
360
361 dst = tempImage;
362 for (img = 0; img < srcDepth; img++) {
363 const GLubyte *src
364 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
365 srcWidth, srcHeight,
366 srcFormat, srcType,
367 img, 0, 0);
368 for (row = 0; row < srcHeight; row++) {
369 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
370 dst, srcFormat, srcType, src,
371 srcPacking, transferOps);
372 dst += srcWidth * components;
373 src += srcStride;
374 }
375 }
376
377 if (logicalBaseFormat != textureBaseFormat) {
378 /* more work */
379 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
380 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
381 GLfloat *newImage;
382 GLint i, n;
383 GLubyte map[6];
384
385 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
386 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
387 textureBaseFormat == GL_LUMINANCE_ALPHA);
388
389 /* The actual texture format should have at least as many components
390 * as the logical texture format.
391 */
392 ASSERT(texComponents >= logComponents);
393
394 newImage = malloc(srcWidth * srcHeight * srcDepth
395 * texComponents * sizeof(GLfloat));
396 if (!newImage) {
397 free(tempImage);
398 return NULL;
399 }
400
401 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
402
403 n = srcWidth * srcHeight * srcDepth;
404 for (i = 0; i < n; i++) {
405 GLint k;
406 for (k = 0; k < texComponents; k++) {
407 GLint j = map[k];
408 if (j == ZERO)
409 newImage[i * texComponents + k] = 0.0F;
410 else if (j == ONE)
411 newImage[i * texComponents + k] = 1.0F;
412 else
413 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
414 }
415 }
416
417 free(tempImage);
418 tempImage = newImage;
419 }
420
421 return tempImage;
422 }
423
424
425 /**
426 * Make temporary image with uint pixel values. Used for unsigned
427 * integer-valued textures.
428 */
429 static GLuint *
430 make_temp_uint_image(struct gl_context *ctx, GLuint dims,
431 GLenum logicalBaseFormat,
432 GLenum textureBaseFormat,
433 GLint srcWidth, GLint srcHeight, GLint srcDepth,
434 GLenum srcFormat, GLenum srcType,
435 const GLvoid *srcAddr,
436 const struct gl_pixelstore_attrib *srcPacking)
437 {
438 GLuint *tempImage;
439 const GLint components = _mesa_components_in_format(logicalBaseFormat);
440 const GLint srcStride =
441 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
442 GLuint *dst;
443 GLint img, row;
444
445 ASSERT(dims >= 1 && dims <= 3);
446
447 ASSERT(logicalBaseFormat == GL_RGBA ||
448 logicalBaseFormat == GL_RGB ||
449 logicalBaseFormat == GL_RG ||
450 logicalBaseFormat == GL_RED ||
451 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
452 logicalBaseFormat == GL_LUMINANCE ||
453 logicalBaseFormat == GL_INTENSITY ||
454 logicalBaseFormat == GL_ALPHA);
455
456 ASSERT(textureBaseFormat == GL_RGBA ||
457 textureBaseFormat == GL_RGB ||
458 textureBaseFormat == GL_RG ||
459 textureBaseFormat == GL_RED ||
460 textureBaseFormat == GL_LUMINANCE_ALPHA ||
461 textureBaseFormat == GL_LUMINANCE ||
462 textureBaseFormat == GL_INTENSITY ||
463 textureBaseFormat == GL_ALPHA);
464
465 tempImage = malloc(srcWidth * srcHeight * srcDepth
466 * components * sizeof(GLuint));
467 if (!tempImage)
468 return NULL;
469
470 dst = tempImage;
471 for (img = 0; img < srcDepth; img++) {
472 const GLubyte *src
473 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
474 srcWidth, srcHeight,
475 srcFormat, srcType,
476 img, 0, 0);
477 for (row = 0; row < srcHeight; row++) {
478 _mesa_unpack_color_span_uint(ctx, srcWidth, logicalBaseFormat,
479 dst, srcFormat, srcType, src,
480 srcPacking);
481 dst += srcWidth * components;
482 src += srcStride;
483 }
484 }
485
486 if (logicalBaseFormat != textureBaseFormat) {
487 /* more work */
488 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
489 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
490 GLuint *newImage;
491 GLint i, n;
492 GLubyte map[6];
493
494 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
495 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
496 textureBaseFormat == GL_LUMINANCE_ALPHA);
497
498 /* The actual texture format should have at least as many components
499 * as the logical texture format.
500 */
501 ASSERT(texComponents >= logComponents);
502
503 newImage = malloc(srcWidth * srcHeight * srcDepth
504 * texComponents * sizeof(GLuint));
505 if (!newImage) {
506 free(tempImage);
507 return NULL;
508 }
509
510 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
511
512 n = srcWidth * srcHeight * srcDepth;
513 for (i = 0; i < n; i++) {
514 GLint k;
515 for (k = 0; k < texComponents; k++) {
516 GLint j = map[k];
517 if (j == ZERO)
518 newImage[i * texComponents + k] = 0;
519 else if (j == ONE)
520 newImage[i * texComponents + k] = 1;
521 else
522 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
523 }
524 }
525
526 free(tempImage);
527 tempImage = newImage;
528 }
529
530 return tempImage;
531 }
532
533
534
535 /**
536 * Make a temporary (color) texture image with GLubyte components.
537 * Apply all needed pixel unpacking and pixel transfer operations.
538 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
539 * Suppose the user specifies GL_LUMINANCE as the internal texture format
540 * but the graphics hardware doesn't support luminance textures. So, we might
541 * use an RGB hardware format instead.
542 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
543 *
544 * \param ctx the rendering context
545 * \param dims image dimensions: 1, 2 or 3
546 * \param logicalBaseFormat basic texture derived from the user's
547 * internal texture format value
548 * \param textureBaseFormat the actual basic format of the texture
549 * \param srcWidth source image width
550 * \param srcHeight source image height
551 * \param srcDepth source image depth
552 * \param srcFormat source image format
553 * \param srcType source image type
554 * \param srcAddr source image address
555 * \param srcPacking source image pixel packing
556 * \return resulting image with format = textureBaseFormat and type = GLubyte.
557 */
558 GLubyte *
559 _mesa_make_temp_ubyte_image(struct gl_context *ctx, GLuint dims,
560 GLenum logicalBaseFormat,
561 GLenum textureBaseFormat,
562 GLint srcWidth, GLint srcHeight, GLint srcDepth,
563 GLenum srcFormat, GLenum srcType,
564 const GLvoid *srcAddr,
565 const struct gl_pixelstore_attrib *srcPacking)
566 {
567 GLuint transferOps = ctx->_ImageTransferState;
568 const GLint components = _mesa_components_in_format(logicalBaseFormat);
569 GLint img, row;
570 GLubyte *tempImage, *dst;
571
572 ASSERT(dims >= 1 && dims <= 3);
573
574 ASSERT(logicalBaseFormat == GL_RGBA ||
575 logicalBaseFormat == GL_RGB ||
576 logicalBaseFormat == GL_RG ||
577 logicalBaseFormat == GL_RED ||
578 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
579 logicalBaseFormat == GL_LUMINANCE ||
580 logicalBaseFormat == GL_ALPHA ||
581 logicalBaseFormat == GL_INTENSITY);
582
583 ASSERT(textureBaseFormat == GL_RGBA ||
584 textureBaseFormat == GL_RGB ||
585 textureBaseFormat == GL_RG ||
586 textureBaseFormat == GL_RED ||
587 textureBaseFormat == GL_LUMINANCE_ALPHA ||
588 textureBaseFormat == GL_LUMINANCE ||
589 textureBaseFormat == GL_ALPHA ||
590 textureBaseFormat == GL_INTENSITY);
591
592 /* unpack and transfer the source image */
593 tempImage = malloc(srcWidth * srcHeight * srcDepth
594 * components * sizeof(GLubyte));
595 if (!tempImage) {
596 return NULL;
597 }
598
599 dst = tempImage;
600 for (img = 0; img < srcDepth; img++) {
601 const GLint srcStride =
602 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
603 const GLubyte *src =
604 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
605 srcWidth, srcHeight,
606 srcFormat, srcType,
607 img, 0, 0);
608 for (row = 0; row < srcHeight; row++) {
609 _mesa_unpack_color_span_ubyte(ctx, srcWidth, logicalBaseFormat, dst,
610 srcFormat, srcType, src, srcPacking,
611 transferOps);
612 dst += srcWidth * components;
613 src += srcStride;
614 }
615 }
616
617 if (logicalBaseFormat != textureBaseFormat) {
618 /* one more conversion step */
619 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
620 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
621 GLubyte *newImage;
622 GLint i, n;
623 GLubyte map[6];
624
625 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
626 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
627 textureBaseFormat == GL_LUMINANCE_ALPHA);
628
629 /* The actual texture format should have at least as many components
630 * as the logical texture format.
631 */
632 ASSERT(texComponents >= logComponents);
633
634 newImage = malloc(srcWidth * srcHeight * srcDepth
635 * texComponents * sizeof(GLubyte));
636 if (!newImage) {
637 free(tempImage);
638 return NULL;
639 }
640
641 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
642
643 n = srcWidth * srcHeight * srcDepth;
644 for (i = 0; i < n; i++) {
645 GLint k;
646 for (k = 0; k < texComponents; k++) {
647 GLint j = map[k];
648 if (j == ZERO)
649 newImage[i * texComponents + k] = 0;
650 else if (j == ONE)
651 newImage[i * texComponents + k] = 255;
652 else
653 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
654 }
655 }
656
657 free(tempImage);
658 tempImage = newImage;
659 }
660
661 return tempImage;
662 }
663
664
665 /**
666 * Copy GLubyte pixels from <src> to <dst> with swizzling.
667 * \param dst destination pixels
668 * \param dstComponents number of color components in destination pixels
669 * \param src source pixels
670 * \param srcComponents number of color components in source pixels
671 * \param map the swizzle mapping. map[X] says where to find the X component
672 * in the source image's pixels. For example, if the source image
673 * is GL_BGRA and X = red, map[0] yields 2.
674 * \param count number of pixels to copy/swizzle.
675 */
676 static void
677 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
678 GLuint srcComponents, const GLubyte *map, GLuint count)
679 {
680 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
681 do { \
682 GLuint i; \
683 for (i = 0; i < count; i++) { \
684 GLuint j; \
685 if (srcComps == 4) { \
686 COPY_4UBV(tmp, src); \
687 } \
688 else { \
689 for (j = 0; j < srcComps; j++) { \
690 tmp[j] = src[j]; \
691 } \
692 } \
693 src += srcComps; \
694 for (j = 0; j < dstComps; j++) { \
695 dst[j] = tmp[map[j]]; \
696 } \
697 dst += dstComps; \
698 } \
699 } while (0)
700
701 GLubyte tmp[6];
702
703 tmp[ZERO] = 0x0;
704 tmp[ONE] = 0xff;
705
706 ASSERT(srcComponents <= 4);
707 ASSERT(dstComponents <= 4);
708
709 switch (dstComponents) {
710 case 4:
711 switch (srcComponents) {
712 case 4:
713 SWZ_CPY(dst, src, count, 4, 4);
714 break;
715 case 3:
716 SWZ_CPY(dst, src, count, 4, 3);
717 break;
718 case 2:
719 SWZ_CPY(dst, src, count, 4, 2);
720 break;
721 case 1:
722 SWZ_CPY(dst, src, count, 4, 1);
723 break;
724 default:
725 ;
726 }
727 break;
728 case 3:
729 switch (srcComponents) {
730 case 4:
731 SWZ_CPY(dst, src, count, 3, 4);
732 break;
733 case 3:
734 SWZ_CPY(dst, src, count, 3, 3);
735 break;
736 case 2:
737 SWZ_CPY(dst, src, count, 3, 2);
738 break;
739 case 1:
740 SWZ_CPY(dst, src, count, 3, 1);
741 break;
742 default:
743 ;
744 }
745 break;
746 case 2:
747 switch (srcComponents) {
748 case 4:
749 SWZ_CPY(dst, src, count, 2, 4);
750 break;
751 case 3:
752 SWZ_CPY(dst, src, count, 2, 3);
753 break;
754 case 2:
755 SWZ_CPY(dst, src, count, 2, 2);
756 break;
757 case 1:
758 SWZ_CPY(dst, src, count, 2, 1);
759 break;
760 default:
761 ;
762 }
763 break;
764 case 1:
765 switch (srcComponents) {
766 case 4:
767 SWZ_CPY(dst, src, count, 1, 4);
768 break;
769 case 3:
770 SWZ_CPY(dst, src, count, 1, 3);
771 break;
772 case 2:
773 SWZ_CPY(dst, src, count, 1, 2);
774 break;
775 case 1:
776 SWZ_CPY(dst, src, count, 1, 1);
777 break;
778 default:
779 ;
780 }
781 break;
782 default:
783 ;
784 }
785 #undef SWZ_CPY
786 }
787
788
789
790 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
791 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
792
793
794 /**
795 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
796 * mapping array depending on endianness.
797 */
798 static const GLubyte *
799 type_mapping( GLenum srcType )
800 {
801 switch (srcType) {
802 case GL_BYTE:
803 case GL_UNSIGNED_BYTE:
804 return map_identity;
805 case GL_UNSIGNED_INT_8_8_8_8:
806 return _mesa_little_endian() ? map_3210 : map_identity;
807 case GL_UNSIGNED_INT_8_8_8_8_REV:
808 return _mesa_little_endian() ? map_identity : map_3210;
809 default:
810 return NULL;
811 }
812 }
813
814
815 /**
816 * For 1-byte/pixel formats (or 8_8_8_8 packed formats), return a
817 * mapping array depending on pixelstore byte swapping state.
818 */
819 static const GLubyte *
820 byteswap_mapping( GLboolean swapBytes,
821 GLenum srcType )
822 {
823 if (!swapBytes)
824 return map_identity;
825
826 switch (srcType) {
827 case GL_BYTE:
828 case GL_UNSIGNED_BYTE:
829 return map_identity;
830 case GL_UNSIGNED_INT_8_8_8_8:
831 case GL_UNSIGNED_INT_8_8_8_8_REV:
832 return map_3210;
833 default:
834 return NULL;
835 }
836 }
837
838
839
840 /**
841 * Transfer a GLubyte texture image with component swizzling.
842 */
843 static void
844 _mesa_swizzle_ubyte_image(struct gl_context *ctx,
845 GLuint dimensions,
846 GLenum srcFormat,
847 GLenum srcType,
848
849 GLenum baseInternalFormat,
850
851 const GLubyte *rgba2dst,
852 GLuint dstComponents,
853
854 GLint 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 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
900 srcWidth * srcHeight);
901 }
902 else {
903 GLint img, row;
904 for (img = 0; img < srcDepth; img++) {
905 const GLubyte *srcRow = srcImage;
906 GLubyte *dstRow = dstSlices[img];
907 for (row = 0; row < srcHeight; row++) {
908 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
909 dstRow += dstRowStride;
910 srcRow += srcRowStride;
911 }
912 srcImage += srcImageStride;
913 }
914 }
915 }
916
917
918 /**
919 * Teximage storage routine for when a simple memcpy will do.
920 * No pixel transfer operations or special texel encodings allowed.
921 * 1D, 2D and 3D images supported.
922 */
923 static void
924 memcpy_texture(struct gl_context *ctx,
925 GLuint dimensions,
926 mesa_format dstFormat,
927 GLint dstRowStride,
928 GLubyte **dstSlices,
929 GLint srcWidth, GLint srcHeight, GLint srcDepth,
930 GLenum srcFormat, GLenum srcType,
931 const GLvoid *srcAddr,
932 const struct gl_pixelstore_attrib *srcPacking)
933 {
934 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
935 srcFormat, srcType);
936 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
937 srcWidth, srcHeight, srcFormat, srcType);
938 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
939 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
940 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
941 const GLint bytesPerRow = srcWidth * texelBytes;
942
943 if (dstRowStride == srcRowStride &&
944 dstRowStride == bytesPerRow) {
945 /* memcpy image by image */
946 GLint img;
947 for (img = 0; img < srcDepth; img++) {
948 GLubyte *dstImage = dstSlices[img];
949 memcpy(dstImage, srcImage, bytesPerRow * srcHeight);
950 srcImage += srcImageStride;
951 }
952 }
953 else {
954 /* memcpy row by row */
955 GLint img, row;
956 for (img = 0; img < srcDepth; img++) {
957 const GLubyte *srcRow = srcImage;
958 GLubyte *dstRow = dstSlices[img];
959 for (row = 0; row < srcHeight; row++) {
960 memcpy(dstRow, srcRow, bytesPerRow);
961 dstRow += dstRowStride;
962 srcRow += srcRowStride;
963 }
964 srcImage += srcImageStride;
965 }
966 }
967 }
968
969
970 /**
971 * General-case function for storing a color texture images with
972 * components that can be represented with ubytes. Example destination
973 * texture formats are MESA_FORMAT_ARGB888, ARGB4444, RGB565.
974 */
975 static GLboolean
976 store_ubyte_texture(TEXSTORE_PARAMS)
977 {
978 const GLint srcRowStride = srcWidth * 4 * sizeof(GLubyte);
979 GLubyte *tempImage, *src;
980 GLint img;
981
982 tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
983 baseInternalFormat,
984 GL_RGBA,
985 srcWidth, srcHeight, srcDepth,
986 srcFormat, srcType, srcAddr,
987 srcPacking);
988 if (!tempImage)
989 return GL_FALSE;
990
991 src = tempImage;
992 for (img = 0; img < srcDepth; img++) {
993 _mesa_pack_ubyte_rgba_rect(dstFormat, srcWidth, srcHeight,
994 src, srcRowStride,
995 dstSlices[img], dstRowStride);
996 src += srcHeight * srcRowStride;
997 }
998 free(tempImage);
999
1000 return GL_TRUE;
1001 }
1002
1003
1004
1005
1006 /**
1007 * Store a 32-bit integer or float depth component texture image.
1008 */
1009 static GLboolean
1010 _mesa_texstore_z32(TEXSTORE_PARAMS)
1011 {
1012 const GLuint depthScale = 0xffffffff;
1013 GLenum dstType;
1014 (void) dims;
1015 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM32 ||
1016 dstFormat == MESA_FORMAT_Z_FLOAT32);
1017 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLuint));
1018
1019 if (dstFormat == MESA_FORMAT_Z_UNORM32)
1020 dstType = GL_UNSIGNED_INT;
1021 else
1022 dstType = GL_FLOAT;
1023
1024 {
1025 /* general path */
1026 GLint img, row;
1027 for (img = 0; img < srcDepth; img++) {
1028 GLubyte *dstRow = dstSlices[img];
1029 for (row = 0; row < srcHeight; row++) {
1030 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1031 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1032 _mesa_unpack_depth_span(ctx, srcWidth,
1033 dstType, dstRow,
1034 depthScale, srcType, src, srcPacking);
1035 dstRow += dstRowStride;
1036 }
1037 }
1038 }
1039 return GL_TRUE;
1040 }
1041
1042
1043 /**
1044 * Store a 24-bit integer depth component texture image.
1045 */
1046 static GLboolean
1047 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1048 {
1049 const GLuint depthScale = 0xffffff;
1050
1051 (void) dims;
1052 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_X8_UINT);
1053
1054 {
1055 /* general path */
1056 GLint img, row;
1057 for (img = 0; img < srcDepth; img++) {
1058 GLubyte *dstRow = dstSlices[img];
1059 for (row = 0; row < srcHeight; row++) {
1060 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1061 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1062 _mesa_unpack_depth_span(ctx, srcWidth,
1063 GL_UNSIGNED_INT, (GLuint *) dstRow,
1064 depthScale, srcType, src, srcPacking);
1065 dstRow += dstRowStride;
1066 }
1067 }
1068 }
1069 return GL_TRUE;
1070 }
1071
1072
1073 /**
1074 * Store a 24-bit integer depth component texture image.
1075 */
1076 static GLboolean
1077 _mesa_texstore_z24_x8(TEXSTORE_PARAMS)
1078 {
1079 const GLuint depthScale = 0xffffff;
1080
1081 (void) dims;
1082 ASSERT(dstFormat == MESA_FORMAT_X8_UINT_Z24_UNORM);
1083
1084 {
1085 /* general path */
1086 GLint img, row;
1087 for (img = 0; img < srcDepth; img++) {
1088 GLubyte *dstRow = dstSlices[img];
1089 for (row = 0; row < srcHeight; row++) {
1090 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1091 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1092 GLuint *dst = (GLuint *) dstRow;
1093 GLint i;
1094 _mesa_unpack_depth_span(ctx, srcWidth,
1095 GL_UNSIGNED_INT, dst,
1096 depthScale, srcType, src, srcPacking);
1097 for (i = 0; i < srcWidth; i++)
1098 dst[i] <<= 8;
1099 dstRow += dstRowStride;
1100 }
1101 }
1102 }
1103 return GL_TRUE;
1104 }
1105
1106
1107 /**
1108 * Store a 16-bit integer depth component texture image.
1109 */
1110 static GLboolean
1111 _mesa_texstore_z16(TEXSTORE_PARAMS)
1112 {
1113 const GLuint depthScale = 0xffff;
1114 (void) dims;
1115 ASSERT(dstFormat == MESA_FORMAT_Z_UNORM16);
1116 ASSERT(_mesa_get_format_bytes(dstFormat) == sizeof(GLushort));
1117
1118 {
1119 /* general path */
1120 GLint img, row;
1121 for (img = 0; img < srcDepth; img++) {
1122 GLubyte *dstRow = dstSlices[img];
1123 for (row = 0; row < srcHeight; row++) {
1124 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1125 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1126 GLushort *dst16 = (GLushort *) dstRow;
1127 _mesa_unpack_depth_span(ctx, srcWidth,
1128 GL_UNSIGNED_SHORT, dst16, depthScale,
1129 srcType, src, srcPacking);
1130 dstRow += dstRowStride;
1131 }
1132 }
1133 }
1134 return GL_TRUE;
1135 }
1136
1137
1138 /**
1139 * Store an rgb565 or rgb565_rev texture image.
1140 */
1141 static GLboolean
1142 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1143 {
1144 ASSERT(dstFormat == MESA_FORMAT_B5G6R5_UNORM ||
1145 dstFormat == MESA_FORMAT_R5G6B5_UNORM);
1146 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1147
1148 if (!ctx->_ImageTransferState &&
1149 !srcPacking->SwapBytes &&
1150 baseInternalFormat == GL_RGB &&
1151 srcFormat == GL_RGB &&
1152 srcType == GL_UNSIGNED_BYTE &&
1153 dims == 2) {
1154 /* do optimized tex store */
1155 const GLint srcRowStride =
1156 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1157 const GLubyte *src = (const GLubyte *)
1158 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1159 srcFormat, srcType, 0, 0, 0);
1160 GLubyte *dst = dstSlices[0];
1161 GLint row, col;
1162 for (row = 0; row < srcHeight; row++) {
1163 const GLubyte *srcUB = (const GLubyte *) src;
1164 GLushort *dstUS = (GLushort *) dst;
1165 /* check for byteswapped format */
1166 if (dstFormat == MESA_FORMAT_B5G6R5_UNORM) {
1167 for (col = 0; col < srcWidth; col++) {
1168 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1169 srcUB += 3;
1170 }
1171 }
1172 else {
1173 for (col = 0; col < srcWidth; col++) {
1174 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1175 srcUB += 3;
1176 }
1177 }
1178 dst += dstRowStride;
1179 src += srcRowStride;
1180 }
1181 }
1182 else {
1183 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1184 dstFormat, dstRowStride, dstSlices,
1185 srcWidth, srcHeight, srcDepth,
1186 srcFormat, srcType, srcAddr, srcPacking);
1187 }
1188 return GL_TRUE;
1189 }
1190
1191
1192 /**
1193 * Store a texture in MESA_FORMAT_A8B8G8R8_UNORM or MESA_FORMAT_R8G8B8A8_UNORM.
1194 */
1195 static GLboolean
1196 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1197 {
1198 const GLboolean littleEndian = _mesa_little_endian();
1199
1200 ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_UNORM ||
1201 dstFormat == MESA_FORMAT_R8G8B8A8_UNORM ||
1202 dstFormat == MESA_FORMAT_X8B8G8R8_UNORM ||
1203 dstFormat == MESA_FORMAT_R8G8B8X8_UNORM);
1204 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1205
1206 if (!ctx->_ImageTransferState &&
1207 (srcType == GL_UNSIGNED_BYTE ||
1208 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1209 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1210 can_swizzle(baseInternalFormat) &&
1211 can_swizzle(srcFormat)) {
1212
1213 GLubyte dstmap[4];
1214
1215 /* dstmap - how to swizzle from RGBA to dst format:
1216 */
1217 if ((littleEndian && (dstFormat == MESA_FORMAT_A8B8G8R8_UNORM ||
1218 dstFormat == MESA_FORMAT_X8B8G8R8_UNORM)) ||
1219 (!littleEndian && (dstFormat == MESA_FORMAT_R8G8B8A8_UNORM ||
1220 dstFormat == MESA_FORMAT_R8G8B8X8_UNORM))) {
1221 dstmap[3] = 0;
1222 dstmap[2] = 1;
1223 dstmap[1] = 2;
1224 dstmap[0] = 3;
1225 }
1226 else {
1227 dstmap[3] = 3;
1228 dstmap[2] = 2;
1229 dstmap[1] = 1;
1230 dstmap[0] = 0;
1231 }
1232
1233 _mesa_swizzle_ubyte_image(ctx, dims,
1234 srcFormat,
1235 srcType,
1236 baseInternalFormat,
1237 dstmap, 4,
1238 dstRowStride, dstSlices,
1239 srcWidth, srcHeight, srcDepth, srcAddr,
1240 srcPacking);
1241 }
1242 else {
1243 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1244 dstFormat, dstRowStride, dstSlices,
1245 srcWidth, srcHeight, srcDepth,
1246 srcFormat, srcType, srcAddr, srcPacking);
1247 }
1248 return GL_TRUE;
1249 }
1250
1251
1252 static GLboolean
1253 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1254 {
1255 const GLboolean littleEndian = _mesa_little_endian();
1256
1257 ASSERT(dstFormat == MESA_FORMAT_B8G8R8A8_UNORM ||
1258 dstFormat == MESA_FORMAT_A8R8G8B8_UNORM ||
1259 dstFormat == MESA_FORMAT_B8G8R8X8_UNORM ||
1260 dstFormat == MESA_FORMAT_X8R8G8B8_UNORM );
1261 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1262
1263 if (!ctx->_ImageTransferState &&
1264 !srcPacking->SwapBytes &&
1265 (dstFormat == MESA_FORMAT_B8G8R8A8_UNORM ||
1266 dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) &&
1267 srcFormat == GL_RGB &&
1268 (baseInternalFormat == GL_RGBA ||
1269 baseInternalFormat == GL_RGB) &&
1270 srcType == GL_UNSIGNED_BYTE) {
1271 int img, row, col;
1272 for (img = 0; img < srcDepth; img++) {
1273 const GLint srcRowStride =
1274 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1275 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1276 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1277 GLubyte *dstRow = dstSlices[img];
1278 for (row = 0; row < srcHeight; row++) {
1279 GLuint *d4 = (GLuint *) dstRow;
1280 for (col = 0; col < srcWidth; col++) {
1281 d4[col] = PACK_COLOR_8888(0xff,
1282 srcRow[col * 3 + RCOMP],
1283 srcRow[col * 3 + GCOMP],
1284 srcRow[col * 3 + BCOMP]);
1285 }
1286 dstRow += dstRowStride;
1287 srcRow += srcRowStride;
1288 }
1289 }
1290 }
1291 else if (!ctx->_ImageTransferState &&
1292 !srcPacking->SwapBytes &&
1293 dstFormat == MESA_FORMAT_B8G8R8A8_UNORM &&
1294 srcFormat == GL_LUMINANCE_ALPHA &&
1295 baseInternalFormat == GL_RGBA &&
1296 srcType == GL_UNSIGNED_BYTE) {
1297 /* special case of storing LA -> ARGB8888 */
1298 int img, row, col;
1299 const GLint srcRowStride =
1300 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1301 for (img = 0; img < srcDepth; img++) {
1302 const GLubyte *srcRow = (const GLubyte *)
1303 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth,
1304 srcHeight, srcFormat, srcType, img, 0, 0);
1305 GLubyte *dstRow = dstSlices[img];
1306 for (row = 0; row < srcHeight; row++) {
1307 GLuint *d4 = (GLuint *) dstRow;
1308 for (col = 0; col < srcWidth; col++) {
1309 GLubyte l = srcRow[col * 2 + 0], a = srcRow[col * 2 + 1];
1310 d4[col] = PACK_COLOR_8888(a, l, l, l);
1311 }
1312 dstRow += dstRowStride;
1313 srcRow += srcRowStride;
1314 }
1315 }
1316 }
1317 else if (!ctx->_ImageTransferState &&
1318 !srcPacking->SwapBytes &&
1319 dstFormat == MESA_FORMAT_B8G8R8A8_UNORM &&
1320 srcFormat == GL_RGBA &&
1321 baseInternalFormat == GL_RGBA &&
1322 srcType == GL_UNSIGNED_BYTE) {
1323 /* same as above case, but src data has alpha too */
1324 GLint img, row, col;
1325 /* For some reason, streaming copies to write-combined regions
1326 * are extremely sensitive to the characteristics of how the
1327 * source data is retrieved. By reordering the source reads to
1328 * be in-order, the speed of this operation increases by half.
1329 * Strangely the same isn't required for the RGB path, above.
1330 */
1331 for (img = 0; img < srcDepth; img++) {
1332 const GLint srcRowStride =
1333 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1334 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1335 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1336 GLubyte *dstRow = dstSlices[img];
1337 for (row = 0; row < srcHeight; row++) {
1338 GLuint *d4 = (GLuint *) dstRow;
1339 for (col = 0; col < srcWidth; col++) {
1340 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1341 srcRow[col * 4 + RCOMP],
1342 srcRow[col * 4 + GCOMP],
1343 srcRow[col * 4 + BCOMP]);
1344 }
1345 dstRow += dstRowStride;
1346 srcRow += srcRowStride;
1347 }
1348 }
1349 }
1350 else if (!ctx->_ImageTransferState &&
1351 (srcType == GL_UNSIGNED_BYTE ||
1352 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1353 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1354 can_swizzle(baseInternalFormat) &&
1355 can_swizzle(srcFormat)) {
1356
1357 GLubyte dstmap[4];
1358
1359 /* dstmap - how to swizzle from RGBA to dst format:
1360 */
1361 if ((littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) ||
1362 (littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM) ||
1363 (!littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) ||
1364 (!littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM)) {
1365 dstmap[3] = 3; /* alpha */
1366 dstmap[2] = 0; /* red */
1367 dstmap[1] = 1; /* green */
1368 dstmap[0] = 2; /* blue */
1369 }
1370 else {
1371 assert((littleEndian && dstFormat == MESA_FORMAT_A8R8G8B8_UNORM) ||
1372 (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8A8_UNORM) ||
1373 (littleEndian && dstFormat == MESA_FORMAT_X8R8G8B8_UNORM) ||
1374 (!littleEndian && dstFormat == MESA_FORMAT_B8G8R8X8_UNORM));
1375 dstmap[3] = 2;
1376 dstmap[2] = 1;
1377 dstmap[1] = 0;
1378 dstmap[0] = 3;
1379 }
1380
1381 _mesa_swizzle_ubyte_image(ctx, dims,
1382 srcFormat,
1383 srcType,
1384 baseInternalFormat,
1385 dstmap, 4,
1386 dstRowStride,
1387 dstSlices,
1388 srcWidth, srcHeight, srcDepth, srcAddr,
1389 srcPacking);
1390 }
1391 else {
1392 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1393 dstFormat, dstRowStride, dstSlices,
1394 srcWidth, srcHeight, srcDepth,
1395 srcFormat, srcType, srcAddr, srcPacking);
1396 }
1397 return GL_TRUE;
1398 }
1399
1400
1401 static GLboolean
1402 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1403 {
1404 ASSERT(dstFormat == MESA_FORMAT_BGR_UNORM8);
1405 ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1406
1407 if (!ctx->_ImageTransferState &&
1408 !srcPacking->SwapBytes &&
1409 srcFormat == GL_RGBA &&
1410 srcType == GL_UNSIGNED_BYTE) {
1411 /* extract RGB from RGBA */
1412 GLint img, row, col;
1413 for (img = 0; img < srcDepth; img++) {
1414 const GLint srcRowStride =
1415 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1416 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1417 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1418 GLubyte *dstRow = dstSlices[img];
1419 for (row = 0; row < srcHeight; row++) {
1420 for (col = 0; col < srcWidth; col++) {
1421 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1422 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1423 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1424 }
1425 dstRow += dstRowStride;
1426 srcRow += srcRowStride;
1427 }
1428 }
1429 }
1430 else if (!ctx->_ImageTransferState &&
1431 srcType == GL_UNSIGNED_BYTE &&
1432 can_swizzle(baseInternalFormat) &&
1433 can_swizzle(srcFormat)) {
1434
1435 GLubyte dstmap[4];
1436
1437 /* dstmap - how to swizzle from RGBA to dst format:
1438 */
1439 dstmap[0] = 2;
1440 dstmap[1] = 1;
1441 dstmap[2] = 0;
1442 dstmap[3] = ONE; /* ? */
1443
1444 _mesa_swizzle_ubyte_image(ctx, dims,
1445 srcFormat,
1446 srcType,
1447 baseInternalFormat,
1448 dstmap, 3,
1449 dstRowStride, dstSlices,
1450 srcWidth, srcHeight, srcDepth, srcAddr,
1451 srcPacking);
1452 }
1453 else {
1454 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1455 dstFormat, dstRowStride, dstSlices,
1456 srcWidth, srcHeight, srcDepth,
1457 srcFormat, srcType, srcAddr, srcPacking);
1458 }
1459 return GL_TRUE;
1460 }
1461
1462
1463 static GLboolean
1464 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1465 {
1466 ASSERT(dstFormat == MESA_FORMAT_RGB_UNORM8);
1467 ASSERT(_mesa_get_format_bytes(dstFormat) == 3);
1468
1469 if (!ctx->_ImageTransferState &&
1470 !srcPacking->SwapBytes &&
1471 srcFormat == GL_RGBA &&
1472 srcType == GL_UNSIGNED_BYTE) {
1473 /* extract BGR from RGBA */
1474 int img, row, col;
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[img];
1481 for (row = 0; row < srcHeight; row++) {
1482 for (col = 0; col < srcWidth; col++) {
1483 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1484 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1485 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1486 }
1487 dstRow += dstRowStride;
1488 srcRow += srcRowStride;
1489 }
1490 }
1491 }
1492 else if (!ctx->_ImageTransferState &&
1493 srcType == GL_UNSIGNED_BYTE &&
1494 can_swizzle(baseInternalFormat) &&
1495 can_swizzle(srcFormat)) {
1496
1497 GLubyte dstmap[4];
1498
1499 /* dstmap - how to swizzle from RGBA to dst format:
1500 */
1501 dstmap[0] = 0;
1502 dstmap[1] = 1;
1503 dstmap[2] = 2;
1504 dstmap[3] = ONE; /* ? */
1505
1506 _mesa_swizzle_ubyte_image(ctx, dims,
1507 srcFormat,
1508 srcType,
1509 baseInternalFormat,
1510 dstmap, 3,
1511 dstRowStride, dstSlices,
1512 srcWidth, srcHeight, srcDepth, srcAddr,
1513 srcPacking);
1514 }
1515 else {
1516 return store_ubyte_texture(ctx, dims, baseInternalFormat,
1517 dstFormat, dstRowStride, dstSlices,
1518 srcWidth, srcHeight, srcDepth,
1519 srcFormat, srcType, srcAddr, srcPacking);
1520 }
1521 return GL_TRUE;
1522 }
1523
1524
1525 static GLboolean
1526 _mesa_texstore_argb2101010(TEXSTORE_PARAMS)
1527 {
1528 ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UNORM ||
1529 dstFormat == MESA_FORMAT_B10G10R10X2_UNORM);
1530 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1531
1532 {
1533 /* general path */
1534 /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0
1535 * if the internal format is RGB. */
1536 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1537 baseInternalFormat,
1538 GL_RGBA,
1539 srcWidth, srcHeight, srcDepth,
1540 srcFormat, srcType, srcAddr,
1541 srcPacking,
1542 ctx->_ImageTransferState);
1543 const GLfloat *src = tempImage;
1544 GLint img, row, col;
1545 if (!tempImage)
1546 return GL_FALSE;
1547 for (img = 0; img < srcDepth; img++) {
1548 GLubyte *dstRow = dstSlices[img];
1549 if (baseInternalFormat == GL_RGBA || baseInternalFormat == GL_RGB) {
1550 for (row = 0; row < srcHeight; row++) {
1551 GLuint *dstUI = (GLuint *) dstRow;
1552 for (col = 0; col < srcWidth; col++) {
1553 GLushort a,r,g,b;
1554
1555 UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
1556 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
1557 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
1558 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
1559 dstUI[col] = PACK_COLOR_2101010_US(a, r, g, b);
1560 src += 4;
1561 }
1562 dstRow += dstRowStride;
1563 }
1564 } else {
1565 ASSERT(0);
1566 }
1567 }
1568 free((void *) tempImage);
1569 }
1570 return GL_TRUE;
1571 }
1572
1573
1574 /**
1575 * Do texstore for 2-channel, 4-bit/channel, unsigned normalized formats.
1576 */
1577 static GLboolean
1578 _mesa_texstore_unorm44(TEXSTORE_PARAMS)
1579 {
1580 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1581
1582 ASSERT(dstFormat == MESA_FORMAT_L4A4_UNORM);
1583 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
1584
1585 {
1586 /* general path */
1587 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1588 baseInternalFormat,
1589 baseFormat,
1590 srcWidth, srcHeight, srcDepth,
1591 srcFormat, srcType, srcAddr,
1592 srcPacking);
1593 const GLubyte *src = tempImage;
1594 GLint img, row, col;
1595 if (!tempImage)
1596 return GL_FALSE;
1597 for (img = 0; img < srcDepth; img++) {
1598 GLubyte *dstRow = dstSlices[img];
1599 for (row = 0; row < srcHeight; row++) {
1600 GLubyte *dstUS = (GLubyte *) dstRow;
1601 for (col = 0; col < srcWidth; col++) {
1602 /* src[0] is luminance, src[1] is alpha */
1603 dstUS[col] = PACK_COLOR_44( src[1],
1604 src[0] );
1605 src += 2;
1606 }
1607 dstRow += dstRowStride;
1608 }
1609 }
1610 free((void *) tempImage);
1611 }
1612 return GL_TRUE;
1613 }
1614
1615
1616 /**
1617 * Do texstore for 2-channel, 8-bit/channel, unsigned normalized formats.
1618 */
1619 static GLboolean
1620 _mesa_texstore_unorm88(TEXSTORE_PARAMS)
1621 {
1622 const GLboolean littleEndian = _mesa_little_endian();
1623 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1624
1625 ASSERT(dstFormat == MESA_FORMAT_L8A8_UNORM ||
1626 dstFormat == MESA_FORMAT_A8L8_UNORM ||
1627 dstFormat == MESA_FORMAT_R8G8_UNORM ||
1628 dstFormat == MESA_FORMAT_G8R8_UNORM);
1629 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1630
1631 if (!ctx->_ImageTransferState &&
1632 littleEndian &&
1633 srcType == GL_UNSIGNED_BYTE &&
1634 can_swizzle(baseInternalFormat) &&
1635 can_swizzle(srcFormat)) {
1636 GLubyte dstmap[4];
1637
1638 /* dstmap - how to swizzle from RGBA to dst format:
1639 */
1640 if (dstFormat == MESA_FORMAT_L8A8_UNORM || dstFormat == MESA_FORMAT_A8L8_UNORM) {
1641 if ((littleEndian && dstFormat == MESA_FORMAT_L8A8_UNORM) ||
1642 (!littleEndian && dstFormat == MESA_FORMAT_A8L8_UNORM)) {
1643 dstmap[0] = 0;
1644 dstmap[1] = 3;
1645 }
1646 else {
1647 dstmap[0] = 3;
1648 dstmap[1] = 0;
1649 }
1650 }
1651 else {
1652 if ((littleEndian && dstFormat == MESA_FORMAT_R8G8_UNORM) ||
1653 (!littleEndian && dstFormat == MESA_FORMAT_G8R8_UNORM)) {
1654 dstmap[0] = 0;
1655 dstmap[1] = 1;
1656 }
1657 else {
1658 dstmap[0] = 1;
1659 dstmap[1] = 0;
1660 }
1661 }
1662 dstmap[2] = ZERO; /* ? */
1663 dstmap[3] = ONE; /* ? */
1664
1665 _mesa_swizzle_ubyte_image(ctx, dims,
1666 srcFormat,
1667 srcType,
1668 baseInternalFormat,
1669 dstmap, 2,
1670 dstRowStride, dstSlices,
1671 srcWidth, srcHeight, srcDepth, srcAddr,
1672 srcPacking);
1673 }
1674 else {
1675 /* general path */
1676 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1677 baseInternalFormat,
1678 baseFormat,
1679 srcWidth, srcHeight, srcDepth,
1680 srcFormat, srcType, srcAddr,
1681 srcPacking);
1682 const GLubyte *src = tempImage;
1683 GLint img, row, col;
1684 if (!tempImage)
1685 return GL_FALSE;
1686 for (img = 0; img < srcDepth; img++) {
1687 GLubyte *dstRow = dstSlices[img];
1688 for (row = 0; row < srcHeight; row++) {
1689 GLushort *dstUS = (GLushort *) dstRow;
1690 if (dstFormat == MESA_FORMAT_L8A8_UNORM ||
1691 dstFormat == MESA_FORMAT_R8G8_UNORM) {
1692 for (col = 0; col < srcWidth; col++) {
1693 /* src[0] is luminance (or R), src[1] is alpha (or G) */
1694 dstUS[col] = PACK_COLOR_88( src[1],
1695 src[0] );
1696 src += 2;
1697 }
1698 }
1699 else {
1700 for (col = 0; col < srcWidth; col++) {
1701 /* src[0] is luminance (or R), src[1] is alpha (or G) */
1702 dstUS[col] = PACK_COLOR_88_REV( src[1],
1703 src[0] );
1704 src += 2;
1705 }
1706 }
1707 dstRow += dstRowStride;
1708 }
1709 }
1710 free((void *) tempImage);
1711 }
1712 return GL_TRUE;
1713 }
1714
1715
1716 /**
1717 * Do texstore for 2-channel, 16-bit/channel, unsigned normalized formats.
1718 */
1719 static GLboolean
1720 _mesa_texstore_unorm1616(TEXSTORE_PARAMS)
1721 {
1722 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1723
1724 ASSERT(dstFormat == MESA_FORMAT_L16A16_UNORM ||
1725 dstFormat == MESA_FORMAT_A16L16_UNORM ||
1726 dstFormat == MESA_FORMAT_R16G16_UNORM ||
1727 dstFormat == MESA_FORMAT_G16R16_UNORM);
1728 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
1729
1730 {
1731 /* general path */
1732 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1733 baseInternalFormat,
1734 baseFormat,
1735 srcWidth, srcHeight, srcDepth,
1736 srcFormat, srcType, srcAddr,
1737 srcPacking,
1738 ctx->_ImageTransferState);
1739 const GLfloat *src = tempImage;
1740 GLint img, row, col;
1741 if (!tempImage)
1742 return GL_FALSE;
1743 for (img = 0; img < srcDepth; img++) {
1744 GLubyte *dstRow = dstSlices[img];
1745 for (row = 0; row < srcHeight; row++) {
1746 GLuint *dstUI = (GLuint *) dstRow;
1747 if (dstFormat == MESA_FORMAT_L16A16_UNORM ||
1748 dstFormat == MESA_FORMAT_R16G16_UNORM) {
1749 for (col = 0; col < srcWidth; col++) {
1750 GLushort l, a;
1751
1752 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1753 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1754 dstUI[col] = PACK_COLOR_1616(a, l);
1755 src += 2;
1756 }
1757 }
1758 else {
1759 for (col = 0; col < srcWidth; col++) {
1760 GLushort l, a;
1761
1762 UNCLAMPED_FLOAT_TO_USHORT(l, src[0]);
1763 UNCLAMPED_FLOAT_TO_USHORT(a, src[1]);
1764 dstUI[col] = PACK_COLOR_1616_REV(a, l);
1765 src += 2;
1766 }
1767 }
1768 dstRow += dstRowStride;
1769 }
1770 }
1771 free((void *) tempImage);
1772 }
1773 return GL_TRUE;
1774 }
1775
1776
1777 /* Texstore for R16, A16, L16, I16. */
1778 static GLboolean
1779 _mesa_texstore_unorm16(TEXSTORE_PARAMS)
1780 {
1781 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1782
1783 ASSERT(dstFormat == MESA_FORMAT_R_UNORM16 ||
1784 dstFormat == MESA_FORMAT_A_UNORM16 ||
1785 dstFormat == MESA_FORMAT_L_UNORM16 ||
1786 dstFormat == MESA_FORMAT_I_UNORM16);
1787 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
1788
1789 {
1790 /* general path */
1791 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1792 baseInternalFormat,
1793 baseFormat,
1794 srcWidth, srcHeight, srcDepth,
1795 srcFormat, srcType, srcAddr,
1796 srcPacking,
1797 ctx->_ImageTransferState);
1798 const GLfloat *src = tempImage;
1799 GLint img, row, col;
1800 if (!tempImage)
1801 return GL_FALSE;
1802 for (img = 0; img < srcDepth; img++) {
1803 GLubyte *dstRow = dstSlices[img];
1804 for (row = 0; row < srcHeight; row++) {
1805 GLushort *dstUS = (GLushort *) dstRow;
1806 for (col = 0; col < srcWidth; col++) {
1807 GLushort r;
1808
1809 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
1810 dstUS[col] = r;
1811 src += 1;
1812 }
1813 dstRow += dstRowStride;
1814 }
1815 }
1816 free((void *) tempImage);
1817 }
1818 return GL_TRUE;
1819 }
1820
1821
1822 static GLboolean
1823 _mesa_texstore_rgba_16(TEXSTORE_PARAMS)
1824 {
1825 ASSERT(dstFormat == MESA_FORMAT_RGBA_UNORM16 ||
1826 dstFormat == MESA_FORMAT_RGBX_UNORM16);
1827 ASSERT(_mesa_get_format_bytes(dstFormat) == 8);
1828
1829 {
1830 /* general path */
1831 /* Hardcode GL_RGBA as the base format, which forces alpha to 1.0
1832 * if the internal format is RGB. */
1833 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1834 baseInternalFormat,
1835 GL_RGBA,
1836 srcWidth, srcHeight, srcDepth,
1837 srcFormat, srcType, srcAddr,
1838 srcPacking,
1839 ctx->_ImageTransferState);
1840 const GLfloat *src = tempImage;
1841 GLint img, row, col;
1842
1843 if (!tempImage)
1844 return GL_FALSE;
1845
1846 for (img = 0; img < srcDepth; img++) {
1847 GLubyte *dstRow = dstSlices[img];
1848 for (row = 0; row < srcHeight; row++) {
1849 GLushort *dstUS = (GLushort *) dstRow;
1850 for (col = 0; col < srcWidth; col++) {
1851 GLushort r, g, b, a;
1852
1853 UNCLAMPED_FLOAT_TO_USHORT(r, src[0]);
1854 UNCLAMPED_FLOAT_TO_USHORT(g, src[1]);
1855 UNCLAMPED_FLOAT_TO_USHORT(b, src[2]);
1856 UNCLAMPED_FLOAT_TO_USHORT(a, src[3]);
1857 dstUS[col*4+0] = r;
1858 dstUS[col*4+1] = g;
1859 dstUS[col*4+2] = b;
1860 dstUS[col*4+3] = a;
1861 src += 4;
1862 }
1863 dstRow += dstRowStride;
1864 }
1865 }
1866 free((void *) tempImage);
1867 }
1868 return GL_TRUE;
1869 }
1870
1871
1872 static GLboolean
1873 _mesa_texstore_signed_rgba_16(TEXSTORE_PARAMS)
1874 {
1875 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1876
1877 ASSERT(dstFormat == MESA_FORMAT_RGB_SNORM16 ||
1878 dstFormat == MESA_FORMAT_RGBA_SNORM16 ||
1879 dstFormat == MESA_FORMAT_RGBX_SNORM16);
1880
1881 {
1882 /* general path */
1883 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
1884 baseInternalFormat,
1885 baseFormat,
1886 srcWidth, srcHeight, srcDepth,
1887 srcFormat, srcType, srcAddr,
1888 srcPacking,
1889 ctx->_ImageTransferState);
1890 const GLfloat *src = tempImage;
1891 const GLuint comps = _mesa_get_format_bytes(dstFormat) / 2;
1892 GLint img, row, col;
1893
1894 if (!tempImage)
1895 return GL_FALSE;
1896
1897 /* Note: tempImage is always float[4] / RGBA. We convert to 1, 2,
1898 * 3 or 4 components/pixel here.
1899 */
1900 for (img = 0; img < srcDepth; img++) {
1901 GLubyte *dstRow = dstSlices[img];
1902 for (row = 0; row < srcHeight; row++) {
1903 GLshort *dstRowS = (GLshort *) dstRow;
1904 if (dstFormat == MESA_FORMAT_RGBA_SNORM16) {
1905 for (col = 0; col < srcWidth; col++) {
1906 GLuint c;
1907 for (c = 0; c < comps; c++) {
1908 GLshort p;
1909 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 4 + c]);
1910 dstRowS[col * comps + c] = p;
1911 }
1912 }
1913 dstRow += dstRowStride;
1914 src += 4 * srcWidth;
1915 }
1916 else if (dstFormat == MESA_FORMAT_RGBX_SNORM16) {
1917 for (col = 0; col < srcWidth; col++) {
1918 GLuint c;
1919
1920 for (c = 0; c < 3; c++) {
1921 GLshort p;
1922 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
1923 dstRowS[col * comps + c] = p;
1924 }
1925 dstRowS[col * comps + 3] = 32767;
1926 }
1927 dstRow += dstRowStride;
1928 src += 3 * srcWidth;
1929 }
1930 else {
1931 for (col = 0; col < srcWidth; col++) {
1932 GLuint c;
1933 for (c = 0; c < comps; c++) {
1934 GLshort p;
1935 UNCLAMPED_FLOAT_TO_SHORT(p, src[col * 3 + c]);
1936 dstRowS[col * comps + c] = p;
1937 }
1938 }
1939 dstRow += dstRowStride;
1940 src += 3 * srcWidth;
1941 }
1942 }
1943 }
1944 free((void *) tempImage);
1945 }
1946 return GL_TRUE;
1947 }
1948
1949
1950 /**
1951 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
1952 */
1953 static GLboolean
1954 _mesa_texstore_unorm8(TEXSTORE_PARAMS)
1955 {
1956 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1957
1958 ASSERT(dstFormat == MESA_FORMAT_A_UNORM8 ||
1959 dstFormat == MESA_FORMAT_L_UNORM8 ||
1960 dstFormat == MESA_FORMAT_I_UNORM8 ||
1961 dstFormat == MESA_FORMAT_R_UNORM8);
1962 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
1963
1964 if (!ctx->_ImageTransferState &&
1965 srcType == GL_UNSIGNED_BYTE &&
1966 can_swizzle(baseInternalFormat) &&
1967 can_swizzle(srcFormat)) {
1968 GLubyte dstmap[4];
1969
1970 /* dstmap - how to swizzle from RGBA to dst format:
1971 */
1972 if (dstFormat == MESA_FORMAT_A_UNORM8) {
1973 dstmap[0] = 3;
1974 }
1975 else {
1976 dstmap[0] = 0;
1977 }
1978 dstmap[1] = ZERO; /* ? */
1979 dstmap[2] = ZERO; /* ? */
1980 dstmap[3] = ONE; /* ? */
1981
1982 _mesa_swizzle_ubyte_image(ctx, dims,
1983 srcFormat,
1984 srcType,
1985 baseInternalFormat,
1986 dstmap, 1,
1987 dstRowStride, dstSlices,
1988 srcWidth, srcHeight, srcDepth, srcAddr,
1989 srcPacking);
1990 }
1991 else {
1992 /* general path */
1993 const GLubyte *tempImage = _mesa_make_temp_ubyte_image(ctx, dims,
1994 baseInternalFormat,
1995 baseFormat,
1996 srcWidth, srcHeight, srcDepth,
1997 srcFormat, srcType, srcAddr,
1998 srcPacking);
1999 const GLubyte *src = tempImage;
2000 GLint img, row, col;
2001 if (!tempImage)
2002 return GL_FALSE;
2003 for (img = 0; img < srcDepth; img++) {
2004 GLubyte *dstRow = dstSlices[img];
2005 for (row = 0; row < srcHeight; row++) {
2006 for (col = 0; col < srcWidth; col++) {
2007 dstRow[col] = src[col];
2008 }
2009 dstRow += dstRowStride;
2010 src += srcWidth;
2011 }
2012 }
2013 free((void *) tempImage);
2014 }
2015 return GL_TRUE;
2016 }
2017
2018
2019
2020 /**
2021 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2022 */
2023 static GLboolean
2024 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2025 {
2026 const GLboolean littleEndian = _mesa_little_endian();
2027
2028 (void) ctx; (void) dims; (void) baseInternalFormat;
2029
2030 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2031 (dstFormat == MESA_FORMAT_YCBCR_REV));
2032 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2033 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2034 ASSERT(srcFormat == GL_YCBCR_MESA);
2035 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2036 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2037 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2038
2039 /* always just memcpy since no pixel transfer ops apply */
2040 memcpy_texture(ctx, dims,
2041 dstFormat,
2042 dstRowStride, dstSlices,
2043 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2044 srcAddr, srcPacking);
2045
2046 /* Check if we need byte swapping */
2047 /* XXX the logic here _might_ be wrong */
2048 if (srcPacking->SwapBytes ^
2049 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2050 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2051 !littleEndian) {
2052 GLint img, row;
2053 for (img = 0; img < srcDepth; img++) {
2054 GLubyte *dstRow = dstSlices[img];
2055 for (row = 0; row < srcHeight; row++) {
2056 _mesa_swap2((GLushort *) dstRow, srcWidth);
2057 dstRow += dstRowStride;
2058 }
2059 }
2060 }
2061 return GL_TRUE;
2062 }
2063
2064 static GLboolean
2065 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2066 {
2067 const GLboolean littleEndian = _mesa_little_endian();
2068 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2069
2070 ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2071 ASSERT(texelBytes == 2);
2072 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2073 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2074 (srcFormat == GL_DUDV_ATI));
2075 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2076
2077 if (srcType == GL_BYTE) {
2078 GLubyte dstmap[4];
2079
2080 /* dstmap - how to swizzle from RGBA to dst format:
2081 */
2082 if (littleEndian) {
2083 dstmap[0] = 0;
2084 dstmap[1] = 3;
2085 }
2086 else {
2087 dstmap[0] = 3;
2088 dstmap[1] = 0;
2089 }
2090 dstmap[2] = ZERO; /* ? */
2091 dstmap[3] = ONE; /* ? */
2092
2093 _mesa_swizzle_ubyte_image(ctx, dims,
2094 GL_LUMINANCE_ALPHA, /* hack */
2095 GL_UNSIGNED_BYTE, /* hack */
2096 GL_LUMINANCE_ALPHA, /* hack */
2097 dstmap, 2,
2098 dstRowStride, dstSlices,
2099 srcWidth, srcHeight, srcDepth, srcAddr,
2100 srcPacking);
2101 }
2102 else {
2103 /* general path - note this is defined for 2d textures only */
2104 const GLint components = _mesa_components_in_format(baseInternalFormat);
2105 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2106 srcFormat, srcType);
2107 GLbyte *tempImage, *dst, *src;
2108 GLint row;
2109
2110 tempImage = malloc(srcWidth * srcHeight * srcDepth
2111 * components * sizeof(GLbyte));
2112 if (!tempImage)
2113 return GL_FALSE;
2114
2115 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2116 srcWidth, srcHeight,
2117 srcFormat, srcType,
2118 0, 0, 0);
2119
2120 dst = tempImage;
2121 for (row = 0; row < srcHeight; row++) {
2122 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2123 dst, srcFormat, srcType, src,
2124 srcPacking, 0);
2125 dst += srcWidth * components;
2126 src += srcStride;
2127 }
2128
2129 src = tempImage;
2130 dst = (GLbyte *) dstSlices[0];
2131 for (row = 0; row < srcHeight; row++) {
2132 memcpy(dst, src, srcWidth * texelBytes);
2133 dst += dstRowStride;
2134 src += srcWidth * texelBytes;
2135 }
2136 free((void *) tempImage);
2137 }
2138 return GL_TRUE;
2139 }
2140
2141
2142 /**
2143 * Store a texture in a signed normalized 8-bit format.
2144 */
2145 static GLboolean
2146 _mesa_texstore_snorm8(TEXSTORE_PARAMS)
2147 {
2148 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2149
2150 ASSERT(dstFormat == MESA_FORMAT_A_SNORM8 ||
2151 dstFormat == MESA_FORMAT_L_SNORM8 ||
2152 dstFormat == MESA_FORMAT_I_SNORM8 ||
2153 dstFormat == MESA_FORMAT_R_SNORM8);
2154 ASSERT(_mesa_get_format_bytes(dstFormat) == 1);
2155
2156 {
2157 /* general path */
2158 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2159 baseInternalFormat,
2160 baseFormat,
2161 srcWidth, srcHeight, srcDepth,
2162 srcFormat, srcType, srcAddr,
2163 srcPacking,
2164 ctx->_ImageTransferState);
2165 const GLfloat *src = tempImage;
2166 GLint img, row, col;
2167 if (!tempImage)
2168 return GL_FALSE;
2169 for (img = 0; img < srcDepth; img++) {
2170 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2171 for (row = 0; row < srcHeight; row++) {
2172 for (col = 0; col < srcWidth; col++) {
2173 dstRow[col] = FLOAT_TO_BYTE_TEX(src[col]);
2174 }
2175 dstRow += dstRowStride;
2176 src += srcWidth;
2177 }
2178 }
2179 free((void *) tempImage);
2180 }
2181 return GL_TRUE;
2182 }
2183
2184
2185 /**
2186 * Store a texture in a signed normalized two-channel 16-bit format.
2187 */
2188 static GLboolean
2189 _mesa_texstore_snorm88(TEXSTORE_PARAMS)
2190 {
2191 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2192
2193 ASSERT(dstFormat == MESA_FORMAT_L8A8_SNORM ||
2194 dstFormat == MESA_FORMAT_G8R8_SNORM ||
2195 dstFormat == MESA_FORMAT_R8G8_SNORM);
2196 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2197
2198 {
2199 /* general path */
2200 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2201 baseInternalFormat,
2202 baseFormat,
2203 srcWidth, srcHeight, srcDepth,
2204 srcFormat, srcType, srcAddr,
2205 srcPacking,
2206 ctx->_ImageTransferState);
2207 const GLfloat *src = tempImage;
2208 GLint img, row, col;
2209 if (!tempImage)
2210 return GL_FALSE;
2211 for (img = 0; img < srcDepth; img++) {
2212 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2213 for (row = 0; row < srcHeight; row++) {
2214 GLushort *dst = (GLushort *) dstRow;
2215
2216 if (dstFormat == MESA_FORMAT_L8A8_SNORM ||
2217 dstFormat == MESA_FORMAT_R8G8_SNORM) {
2218 for (col = 0; col < srcWidth; col++) {
2219 GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
2220 GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
2221
2222 dst[col] = PACK_COLOR_88_REV(l, a);
2223 src += 2;
2224 }
2225 } else {
2226 for (col = 0; col < srcWidth; col++) {
2227 GLubyte l = FLOAT_TO_BYTE_TEX(src[0]);
2228 GLubyte a = FLOAT_TO_BYTE_TEX(src[1]);
2229
2230 dst[col] = PACK_COLOR_88(l, a);
2231 src += 2;
2232 }
2233 }
2234
2235 dstRow += dstRowStride;
2236 }
2237 }
2238 free((void *) tempImage);
2239 }
2240 return GL_TRUE;
2241 }
2242
2243 /* Texstore for signed R16, A16, L16, I16. */
2244 static GLboolean
2245 _mesa_texstore_snorm16(TEXSTORE_PARAMS)
2246 {
2247 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2248
2249 ASSERT(dstFormat == MESA_FORMAT_R_SNORM16 ||
2250 dstFormat == MESA_FORMAT_A_SNORM16 ||
2251 dstFormat == MESA_FORMAT_L_SNORM16 ||
2252 dstFormat == MESA_FORMAT_I_SNORM16);
2253 ASSERT(_mesa_get_format_bytes(dstFormat) == 2);
2254
2255 {
2256 /* general path */
2257 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2258 baseInternalFormat,
2259 baseFormat,
2260 srcWidth, srcHeight, srcDepth,
2261 srcFormat, srcType, srcAddr,
2262 srcPacking,
2263 ctx->_ImageTransferState);
2264 const GLfloat *src = tempImage;
2265 GLint img, row, col;
2266 if (!tempImage)
2267 return GL_FALSE;
2268 for (img = 0; img < srcDepth; img++) {
2269 GLubyte *dstRow = dstSlices[img];
2270 for (row = 0; row < srcHeight; row++) {
2271 GLshort *dstUS = (GLshort *) dstRow;
2272 for (col = 0; col < srcWidth; col++) {
2273 GLushort r;
2274
2275 UNCLAMPED_FLOAT_TO_SHORT(r, src[0]);
2276 dstUS[col] = r;
2277 src += 1;
2278 }
2279 dstRow += dstRowStride;
2280 }
2281 }
2282 free((void *) tempImage);
2283 }
2284 return GL_TRUE;
2285 }
2286
2287 /**
2288 * Do texstore for 2-channel, 16-bit/channel, signed normalized formats.
2289 */
2290 static GLboolean
2291 _mesa_texstore_snorm1616(TEXSTORE_PARAMS)
2292 {
2293 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2294
2295 ASSERT(dstFormat == MESA_FORMAT_LA_SNORM16 ||
2296 dstFormat == MESA_FORMAT_G16R16_SNORM ||
2297 dstFormat == MESA_FORMAT_R16G16_SNORM);
2298 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2299
2300 {
2301 /* general path */
2302 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2303 baseInternalFormat,
2304 baseFormat,
2305 srcWidth, srcHeight, srcDepth,
2306 srcFormat, srcType, srcAddr,
2307 srcPacking,
2308 ctx->_ImageTransferState);
2309 const GLfloat *src = tempImage;
2310 GLint img, row, col;
2311 if (!tempImage)
2312 return GL_FALSE;
2313 for (img = 0; img < srcDepth; img++) {
2314 GLubyte *dstRow = dstSlices[img];
2315 for (row = 0; row < srcHeight; row++) {
2316 GLuint *dst = (GLuint *) dstRow;
2317
2318 if (dstFormat == MESA_FORMAT_LA_SNORM16 ||
2319 dstFormat == MESA_FORMAT_R16G16_SNORM) {
2320 for (col = 0; col < srcWidth; col++) {
2321 GLushort l, a;
2322
2323 UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
2324 UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
2325 dst[col] = PACK_COLOR_1616_REV(l, a);
2326 src += 2;
2327 }
2328 } else {
2329 for (col = 0; col < srcWidth; col++) {
2330 GLushort l, a;
2331
2332 UNCLAMPED_FLOAT_TO_SHORT(l, src[0]);
2333 UNCLAMPED_FLOAT_TO_SHORT(a, src[1]);
2334 dst[col] = PACK_COLOR_1616_REV(l, a);
2335 src += 2;
2336 }
2337 }
2338
2339 dstRow += dstRowStride;
2340 }
2341 }
2342 free((void *) tempImage);
2343 }
2344 return GL_TRUE;
2345 }
2346
2347 /**
2348 * Store a texture in MESA_FORMAT_X8B8G8R8_SNORM or
2349 * MESA_FORMAT_R8G8B8X8_SNORM.
2350 */
2351 static GLboolean
2352 _mesa_texstore_signed_rgbx8888(TEXSTORE_PARAMS)
2353 {
2354 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2355
2356 ASSERT(dstFormat == MESA_FORMAT_X8B8G8R8_SNORM ||
2357 dstFormat == MESA_FORMAT_R8G8B8X8_SNORM);
2358 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2359
2360 {
2361 /* general path */
2362 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2363 baseInternalFormat,
2364 baseFormat,
2365 srcWidth, srcHeight, srcDepth,
2366 srcFormat, srcType, srcAddr,
2367 srcPacking,
2368 ctx->_ImageTransferState);
2369 const GLfloat *srcRow = tempImage;
2370 GLint img, row, col;
2371 if (!tempImage)
2372 return GL_FALSE;
2373 for (img = 0; img < srcDepth; img++) {
2374 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2375 for (row = 0; row < srcHeight; row++) {
2376 GLbyte *dst = dstRow;
2377 if (dstFormat == MESA_FORMAT_X8B8G8R8_SNORM) {
2378 for (col = 0; col < srcWidth; col++) {
2379 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2380 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2381 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2382 dst[0] = 127;
2383 srcRow += 3;
2384 dst += 4;
2385 }
2386 }
2387 else {
2388 for (col = 0; col < srcWidth; col++) {
2389 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2390 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2391 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2392 dst[3] = 127;
2393 srcRow += 3;
2394 dst += 4;
2395 }
2396 }
2397 dstRow += dstRowStride;
2398 }
2399 }
2400 free((void *) tempImage);
2401 }
2402 return GL_TRUE;
2403 }
2404
2405
2406
2407 /**
2408 * Store a texture in MESA_FORMAT_A8B8G8R8_SNORM or
2409 * MESA_FORMAT_R8G8B8A8_SNORM
2410 */
2411 static GLboolean
2412 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2413 {
2414 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2415
2416 ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SNORM ||
2417 dstFormat == MESA_FORMAT_R8G8B8A8_SNORM);
2418 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
2419
2420 {
2421 /* general path */
2422 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2423 baseInternalFormat,
2424 baseFormat,
2425 srcWidth, srcHeight, srcDepth,
2426 srcFormat, srcType, srcAddr,
2427 srcPacking,
2428 ctx->_ImageTransferState);
2429 const GLfloat *srcRow = tempImage;
2430 GLint img, row, col;
2431 if (!tempImage)
2432 return GL_FALSE;
2433 for (img = 0; img < srcDepth; img++) {
2434 GLbyte *dstRow = (GLbyte *) dstSlices[img];
2435 for (row = 0; row < srcHeight; row++) {
2436 GLbyte *dst = dstRow;
2437 if (dstFormat == MESA_FORMAT_A8B8G8R8_SNORM) {
2438 for (col = 0; col < srcWidth; col++) {
2439 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2440 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2441 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2442 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2443 srcRow += 4;
2444 dst += 4;
2445 }
2446 }
2447 else {
2448 for (col = 0; col < srcWidth; col++) {
2449 dst[0] = FLOAT_TO_BYTE_TEX(srcRow[RCOMP]);
2450 dst[1] = FLOAT_TO_BYTE_TEX(srcRow[GCOMP]);
2451 dst[2] = FLOAT_TO_BYTE_TEX(srcRow[BCOMP]);
2452 dst[3] = FLOAT_TO_BYTE_TEX(srcRow[ACOMP]);
2453 srcRow += 4;
2454 dst += 4;
2455 }
2456 }
2457 dstRow += dstRowStride;
2458 }
2459 }
2460 free((void *) tempImage);
2461 }
2462 return GL_TRUE;
2463 }
2464
2465
2466 /**
2467 * Store a combined depth/stencil texture image.
2468 */
2469 static GLboolean
2470 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2471 {
2472 const GLuint depthScale = 0xffffff;
2473 const GLint srcRowStride
2474 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2475 GLint img, row;
2476
2477 ASSERT(dstFormat == MESA_FORMAT_S8_UINT_Z24_UNORM);
2478 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2479 srcFormat == GL_DEPTH_COMPONENT ||
2480 srcFormat == GL_STENCIL_INDEX);
2481 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2482
2483 if (srcFormat == GL_DEPTH_COMPONENT ||
2484 srcFormat == GL_STENCIL_INDEX) {
2485 GLuint *depth = malloc(srcWidth * sizeof(GLuint));
2486 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
2487
2488 if (!depth || !stencil) {
2489 free(depth);
2490 free(stencil);
2491 return GL_FALSE;
2492 }
2493
2494 /* In case we only upload depth we need to preserve the stencil */
2495 for (img = 0; img < srcDepth; img++) {
2496 GLuint *dstRow = (GLuint *) dstSlices[img];
2497 const GLubyte *src
2498 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2499 srcWidth, srcHeight,
2500 srcFormat, srcType,
2501 img, 0, 0);
2502 for (row = 0; row < srcHeight; row++) {
2503 GLint i;
2504 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2505
2506 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2507 keepstencil = GL_TRUE;
2508 }
2509 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2510 keepdepth = GL_TRUE;
2511 }
2512
2513 if (keepdepth == GL_FALSE)
2514 /* the 24 depth bits will be in the low position: */
2515 _mesa_unpack_depth_span(ctx, srcWidth,
2516 GL_UNSIGNED_INT, /* dst type */
2517 keepstencil ? depth : dstRow, /* dst addr */
2518 depthScale,
2519 srcType, src, srcPacking);
2520
2521 if (keepstencil == GL_FALSE)
2522 /* get the 8-bit stencil values */
2523 _mesa_unpack_stencil_span(ctx, srcWidth,
2524 GL_UNSIGNED_BYTE, /* dst type */
2525 stencil, /* dst addr */
2526 srcType, src, srcPacking,
2527 ctx->_ImageTransferState);
2528
2529 for (i = 0; i < srcWidth; i++) {
2530 if (keepstencil)
2531 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2532 else
2533 dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF);
2534 }
2535
2536 src += srcRowStride;
2537 dstRow += dstRowStride / sizeof(GLuint);
2538 }
2539 }
2540
2541 free(depth);
2542 free(stencil);
2543 }
2544 return GL_TRUE;
2545 }
2546
2547
2548 /**
2549 * Store a combined depth/stencil texture image.
2550 */
2551 static GLboolean
2552 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2553 {
2554 const GLuint depthScale = 0xffffff;
2555 const GLint srcRowStride
2556 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2557 GLint img, row;
2558 GLuint *depth;
2559 GLubyte *stencil;
2560
2561 ASSERT(dstFormat == MESA_FORMAT_Z24_UNORM_S8_UINT);
2562 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT ||
2563 srcFormat == GL_DEPTH_COMPONENT ||
2564 srcFormat == GL_STENCIL_INDEX);
2565 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT ||
2566 srcType == GL_UNSIGNED_INT_24_8_EXT);
2567
2568 depth = malloc(srcWidth * sizeof(GLuint));
2569 stencil = malloc(srcWidth * sizeof(GLubyte));
2570
2571 if (!depth || !stencil) {
2572 free(depth);
2573 free(stencil);
2574 return GL_FALSE;
2575 }
2576
2577 for (img = 0; img < srcDepth; img++) {
2578 GLuint *dstRow = (GLuint *) dstSlices[img];
2579 const GLubyte *src
2580 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2581 srcWidth, srcHeight,
2582 srcFormat, srcType,
2583 img, 0, 0);
2584 for (row = 0; row < srcHeight; row++) {
2585 GLint i;
2586 GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE;
2587
2588 if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */
2589 keepstencil = GL_TRUE;
2590 }
2591 else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */
2592 keepdepth = GL_TRUE;
2593 }
2594
2595 if (keepdepth == GL_FALSE)
2596 /* the 24 depth bits will be in the low position: */
2597 _mesa_unpack_depth_span(ctx, srcWidth,
2598 GL_UNSIGNED_INT, /* dst type */
2599 keepstencil ? depth : dstRow, /* dst addr */
2600 depthScale,
2601 srcType, src, srcPacking);
2602
2603 if (keepstencil == GL_FALSE)
2604 /* get the 8-bit stencil values */
2605 _mesa_unpack_stencil_span(ctx, srcWidth,
2606 GL_UNSIGNED_BYTE, /* dst type */
2607 stencil, /* dst addr */
2608 srcType, src, srcPacking,
2609 ctx->_ImageTransferState);
2610
2611 /* merge stencil values into depth values */
2612 for (i = 0; i < srcWidth; i++) {
2613 if (keepstencil)
2614 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2615 else
2616 dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24);
2617
2618 }
2619 src += srcRowStride;
2620 dstRow += dstRowStride / sizeof(GLuint);
2621 }
2622 }
2623
2624 free(depth);
2625 free(stencil);
2626
2627 return GL_TRUE;
2628 }
2629
2630
2631 /**
2632 * Store simple 8-bit/value stencil texture data.
2633 */
2634 static GLboolean
2635 _mesa_texstore_s8(TEXSTORE_PARAMS)
2636 {
2637 ASSERT(dstFormat == MESA_FORMAT_S_UINT8);
2638 ASSERT(srcFormat == GL_STENCIL_INDEX);
2639
2640 {
2641 const GLint srcRowStride
2642 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
2643 GLint img, row;
2644 GLubyte *stencil = malloc(srcWidth * sizeof(GLubyte));
2645
2646 if (!stencil)
2647 return GL_FALSE;
2648
2649 for (img = 0; img < srcDepth; img++) {
2650 GLubyte *dstRow = dstSlices[img];
2651 const GLubyte *src
2652 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2653 srcWidth, srcHeight,
2654 srcFormat, srcType,
2655 img, 0, 0);
2656 for (row = 0; row < srcHeight; row++) {
2657 GLint i;
2658
2659 /* get the 8-bit stencil values */
2660 _mesa_unpack_stencil_span(ctx, srcWidth,
2661 GL_UNSIGNED_BYTE, /* dst type */
2662 stencil, /* dst addr */
2663 srcType, src, srcPacking,
2664 ctx->_ImageTransferState);
2665 /* merge stencil values into depth values */
2666 for (i = 0; i < srcWidth; i++)
2667 dstRow[i] = stencil[i];
2668
2669 src += srcRowStride;
2670 dstRow += dstRowStride / sizeof(GLubyte);
2671 }
2672 }
2673
2674 free(stencil);
2675 }
2676
2677 return GL_TRUE;
2678 }
2679
2680
2681 /**
2682 * Store an image in any of the formats:
2683 * _mesa_texformat_rgba_float32
2684 * _mesa_texformat_rgb_float32
2685 * _mesa_texformat_alpha_float32
2686 * _mesa_texformat_luminance_float32
2687 * _mesa_texformat_luminance_alpha_float32
2688 * _mesa_texformat_intensity_float32
2689 */
2690 static GLboolean
2691 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2692 {
2693 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2694 GLint components = _mesa_components_in_format(baseFormat);
2695
2696 /* this forces alpha to 1 in _mesa_make_temp_float_image */
2697 if (dstFormat == MESA_FORMAT_RGBX_FLOAT32) {
2698 baseFormat = GL_RGBA;
2699 components = 4;
2700 }
2701
2702 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
2703 dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
2704 dstFormat == MESA_FORMAT_A_FLOAT32 ||
2705 dstFormat == MESA_FORMAT_L_FLOAT32 ||
2706 dstFormat == MESA_FORMAT_LA_FLOAT32 ||
2707 dstFormat == MESA_FORMAT_I_FLOAT32 ||
2708 dstFormat == MESA_FORMAT_R_FLOAT32 ||
2709 dstFormat == MESA_FORMAT_RG_FLOAT32 ||
2710 dstFormat == MESA_FORMAT_RGBX_FLOAT32);
2711 ASSERT(baseInternalFormat == GL_RGBA ||
2712 baseInternalFormat == GL_RGB ||
2713 baseInternalFormat == GL_ALPHA ||
2714 baseInternalFormat == GL_LUMINANCE ||
2715 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2716 baseInternalFormat == GL_INTENSITY ||
2717 baseInternalFormat == GL_RED ||
2718 baseInternalFormat == GL_RG);
2719 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLfloat));
2720
2721 {
2722 /* general path */
2723 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2724 baseInternalFormat,
2725 baseFormat,
2726 srcWidth, srcHeight, srcDepth,
2727 srcFormat, srcType, srcAddr,
2728 srcPacking,
2729 ctx->_ImageTransferState);
2730 const GLfloat *srcRow = tempImage;
2731 GLint bytesPerRow;
2732 GLint img, row;
2733 if (!tempImage)
2734 return GL_FALSE;
2735 bytesPerRow = srcWidth * components * sizeof(GLfloat);
2736 for (img = 0; img < srcDepth; img++) {
2737 GLubyte *dstRow = dstSlices[img];
2738 for (row = 0; row < srcHeight; row++) {
2739 memcpy(dstRow, srcRow, bytesPerRow);
2740 dstRow += dstRowStride;
2741 srcRow += srcWidth * components;
2742 }
2743 }
2744
2745 free((void *) tempImage);
2746 }
2747 return GL_TRUE;
2748 }
2749
2750
2751
2752 /**
2753 * As above, but store 16-bit floats.
2754 */
2755 static GLboolean
2756 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2757 {
2758 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2759 GLint components = _mesa_components_in_format(baseFormat);
2760
2761 /* this forces alpha to 1 in _mesa_make_temp_float_image */
2762 if (dstFormat == MESA_FORMAT_RGBX_FLOAT16) {
2763 baseFormat = GL_RGBA;
2764 components = 4;
2765 }
2766
2767 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
2768 dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
2769 dstFormat == MESA_FORMAT_A_FLOAT16 ||
2770 dstFormat == MESA_FORMAT_L_FLOAT16 ||
2771 dstFormat == MESA_FORMAT_LA_FLOAT16 ||
2772 dstFormat == MESA_FORMAT_I_FLOAT16 ||
2773 dstFormat == MESA_FORMAT_R_FLOAT16 ||
2774 dstFormat == MESA_FORMAT_RG_FLOAT16 ||
2775 dstFormat == MESA_FORMAT_RGBX_FLOAT16);
2776 ASSERT(baseInternalFormat == GL_RGBA ||
2777 baseInternalFormat == GL_RGB ||
2778 baseInternalFormat == GL_ALPHA ||
2779 baseInternalFormat == GL_LUMINANCE ||
2780 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2781 baseInternalFormat == GL_INTENSITY ||
2782 baseInternalFormat == GL_RED ||
2783 baseInternalFormat == GL_RG);
2784 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLhalfARB));
2785
2786 {
2787 /* general path */
2788 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
2789 baseInternalFormat,
2790 baseFormat,
2791 srcWidth, srcHeight, srcDepth,
2792 srcFormat, srcType, srcAddr,
2793 srcPacking,
2794 ctx->_ImageTransferState);
2795 const GLfloat *src = tempImage;
2796 GLint img, row;
2797 if (!tempImage)
2798 return GL_FALSE;
2799 for (img = 0; img < srcDepth; img++) {
2800 GLubyte *dstRow = dstSlices[img];
2801 for (row = 0; row < srcHeight; row++) {
2802 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2803 GLint i;
2804 for (i = 0; i < srcWidth * components; i++) {
2805 dstTexel[i] = _mesa_float_to_half(src[i]);
2806 }
2807 dstRow += dstRowStride;
2808 src += srcWidth * components;
2809 }
2810 }
2811
2812 free((void *) tempImage);
2813 }
2814 return GL_TRUE;
2815 }
2816
2817
2818 /* non-normalized, signed int8 */
2819 static GLboolean
2820 _mesa_texstore_rgba_int8(TEXSTORE_PARAMS)
2821 {
2822 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2823 GLint components = _mesa_components_in_format(baseFormat);
2824
2825 /* this forces alpha to 1 in make_temp_uint_image */
2826 if (dstFormat == MESA_FORMAT_RGBX_SINT8) {
2827 baseFormat = GL_RGBA;
2828 components = 4;
2829 }
2830
2831 ASSERT(dstFormat == MESA_FORMAT_R_SINT8 ||
2832 dstFormat == MESA_FORMAT_RG_SINT8 ||
2833 dstFormat == MESA_FORMAT_RGB_SINT8 ||
2834 dstFormat == MESA_FORMAT_RGBA_SINT8 ||
2835 dstFormat == MESA_FORMAT_A_SINT8 ||
2836 dstFormat == MESA_FORMAT_I_SINT8 ||
2837 dstFormat == MESA_FORMAT_L_SINT8 ||
2838 dstFormat == MESA_FORMAT_LA_SINT8 ||
2839 dstFormat == MESA_FORMAT_RGBX_SINT8);
2840 ASSERT(baseInternalFormat == GL_RGBA ||
2841 baseInternalFormat == GL_RGB ||
2842 baseInternalFormat == GL_RG ||
2843 baseInternalFormat == GL_RED ||
2844 baseInternalFormat == GL_ALPHA ||
2845 baseInternalFormat == GL_LUMINANCE ||
2846 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2847 baseInternalFormat == GL_INTENSITY);
2848 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLbyte));
2849
2850 {
2851 /* general path */
2852 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
2853 baseInternalFormat,
2854 baseFormat,
2855 srcWidth, srcHeight, srcDepth,
2856 srcFormat, srcType,
2857 srcAddr,
2858 srcPacking);
2859 const GLuint *src = tempImage;
2860 GLint img, row;
2861 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
2862 if (!tempImage)
2863 return GL_FALSE;
2864 for (img = 0; img < srcDepth; img++) {
2865 GLubyte *dstRow = dstSlices[img];
2866 for (row = 0; row < srcHeight; row++) {
2867 GLbyte *dstTexel = (GLbyte *) dstRow;
2868 GLint i;
2869 if (is_unsigned) {
2870 for (i = 0; i < srcWidth * components; i++) {
2871 dstTexel[i] = (GLbyte) MIN2(src[i], 0x7f);
2872 }
2873 } else {
2874 for (i = 0; i < srcWidth * components; i++) {
2875 dstTexel[i] = (GLbyte) CLAMP((GLint) src[i], -0x80, 0x7f);
2876 }
2877 }
2878 dstRow += dstRowStride;
2879 src += srcWidth * components;
2880 }
2881 }
2882
2883 free((void *) tempImage);
2884 }
2885 return GL_TRUE;
2886 }
2887
2888
2889 /* non-normalized, signed int16 */
2890 static GLboolean
2891 _mesa_texstore_rgba_int16(TEXSTORE_PARAMS)
2892 {
2893 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2894 GLint components = _mesa_components_in_format(baseFormat);
2895
2896 /* this forces alpha to 1 in make_temp_uint_image */
2897 if (dstFormat == MESA_FORMAT_RGBX_SINT16) {
2898 baseFormat = GL_RGBA;
2899 components = 4;
2900 }
2901
2902 ASSERT(dstFormat == MESA_FORMAT_R_SINT16 ||
2903 dstFormat == MESA_FORMAT_RG_SINT16 ||
2904 dstFormat == MESA_FORMAT_RGB_SINT16 ||
2905 dstFormat == MESA_FORMAT_RGBA_SINT16 ||
2906 dstFormat == MESA_FORMAT_A_SINT16 ||
2907 dstFormat == MESA_FORMAT_L_SINT16 ||
2908 dstFormat == MESA_FORMAT_I_SINT16 ||
2909 dstFormat == MESA_FORMAT_LA_SINT16 ||
2910 dstFormat == MESA_FORMAT_RGBX_SINT16);
2911 ASSERT(baseInternalFormat == GL_RGBA ||
2912 baseInternalFormat == GL_RGB ||
2913 baseInternalFormat == GL_RG ||
2914 baseInternalFormat == GL_RED ||
2915 baseInternalFormat == GL_ALPHA ||
2916 baseInternalFormat == GL_LUMINANCE ||
2917 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2918 baseInternalFormat == GL_INTENSITY);
2919 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLshort));
2920
2921 {
2922 /* general path */
2923 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
2924 baseInternalFormat,
2925 baseFormat,
2926 srcWidth, srcHeight, srcDepth,
2927 srcFormat, srcType,
2928 srcAddr,
2929 srcPacking);
2930 const GLuint *src = tempImage;
2931 GLint img, row;
2932 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
2933 if (!tempImage)
2934 return GL_FALSE;
2935 for (img = 0; img < srcDepth; img++) {
2936 GLubyte *dstRow = dstSlices[img];
2937 for (row = 0; row < srcHeight; row++) {
2938 GLshort *dstTexel = (GLshort *) dstRow;
2939 GLint i;
2940 if (is_unsigned) {
2941 for (i = 0; i < srcWidth * components; i++) {
2942 dstTexel[i] = (GLshort) MIN2(src[i], 0x7fff);
2943 }
2944 } else {
2945 for (i = 0; i < srcWidth * components; i++) {
2946 dstTexel[i] = (GLshort)CLAMP((GLint) src[i], -0x8000, 0x7fff);
2947 }
2948 }
2949 dstRow += dstRowStride;
2950 src += srcWidth * components;
2951 }
2952 }
2953
2954 free((void *) tempImage);
2955 }
2956 return GL_TRUE;
2957 }
2958
2959
2960 /* non-normalized, signed int32 */
2961 static GLboolean
2962 _mesa_texstore_rgba_int32(TEXSTORE_PARAMS)
2963 {
2964 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2965 GLint components = _mesa_components_in_format(baseFormat);
2966
2967 /* this forces alpha to 1 in make_temp_uint_image */
2968 if (dstFormat == MESA_FORMAT_RGBX_SINT32) {
2969 baseFormat = GL_RGBA;
2970 components = 4;
2971 }
2972
2973 ASSERT(dstFormat == MESA_FORMAT_R_SINT32 ||
2974 dstFormat == MESA_FORMAT_RG_SINT32 ||
2975 dstFormat == MESA_FORMAT_RGB_SINT32 ||
2976 dstFormat == MESA_FORMAT_RGBA_SINT32 ||
2977 dstFormat == MESA_FORMAT_A_SINT32 ||
2978 dstFormat == MESA_FORMAT_I_SINT32 ||
2979 dstFormat == MESA_FORMAT_L_SINT32 ||
2980 dstFormat == MESA_FORMAT_LA_SINT32 ||
2981 dstFormat == MESA_FORMAT_RGBX_SINT32);
2982 ASSERT(baseInternalFormat == GL_RGBA ||
2983 baseInternalFormat == GL_RGB ||
2984 baseInternalFormat == GL_RG ||
2985 baseInternalFormat == GL_RED ||
2986 baseInternalFormat == GL_ALPHA ||
2987 baseInternalFormat == GL_LUMINANCE ||
2988 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2989 baseInternalFormat == GL_INTENSITY);
2990 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLint));
2991
2992 {
2993 /* general path */
2994 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
2995 baseInternalFormat,
2996 baseFormat,
2997 srcWidth, srcHeight, srcDepth,
2998 srcFormat, srcType,
2999 srcAddr,
3000 srcPacking);
3001 const GLuint *src = tempImage;
3002 GLint img, row;
3003 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3004 if (!tempImage)
3005 return GL_FALSE;
3006 for (img = 0; img < srcDepth; img++) {
3007 GLubyte *dstRow = dstSlices[img];
3008 for (row = 0; row < srcHeight; row++) {
3009 GLint *dstTexel = (GLint *) dstRow;
3010 GLint i;
3011 if (is_unsigned) {
3012 for (i = 0; i < srcWidth * components; i++) {
3013 dstTexel[i] = (GLint) MIN2(src[i], 0x7fffffff);
3014 }
3015 } else {
3016 for (i = 0; i < srcWidth * components; i++) {
3017 dstTexel[i] = (GLint) src[i];
3018 }
3019 }
3020 dstRow += dstRowStride;
3021 src += srcWidth * components;
3022 }
3023 }
3024
3025 free((void *) tempImage);
3026 }
3027 return GL_TRUE;
3028 }
3029
3030
3031 /* non-normalized, unsigned int8 */
3032 static GLboolean
3033 _mesa_texstore_rgba_uint8(TEXSTORE_PARAMS)
3034 {
3035 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3036 GLint components = _mesa_components_in_format(baseFormat);
3037
3038 /* this forces alpha to 1 in make_temp_uint_image */
3039 if (dstFormat == MESA_FORMAT_RGBX_UINT8) {
3040 baseFormat = GL_RGBA;
3041 components = 4;
3042 }
3043
3044 ASSERT(dstFormat == MESA_FORMAT_R_UINT8 ||
3045 dstFormat == MESA_FORMAT_RG_UINT8 ||
3046 dstFormat == MESA_FORMAT_RGB_UINT8 ||
3047 dstFormat == MESA_FORMAT_RGBA_UINT8 ||
3048 dstFormat == MESA_FORMAT_A_UINT8 ||
3049 dstFormat == MESA_FORMAT_I_UINT8 ||
3050 dstFormat == MESA_FORMAT_L_UINT8 ||
3051 dstFormat == MESA_FORMAT_LA_UINT8 ||
3052 dstFormat == MESA_FORMAT_RGBX_UINT8);
3053 ASSERT(baseInternalFormat == GL_RGBA ||
3054 baseInternalFormat == GL_RGB ||
3055 baseInternalFormat == GL_RG ||
3056 baseInternalFormat == GL_RED ||
3057 baseInternalFormat == GL_ALPHA ||
3058 baseInternalFormat == GL_LUMINANCE ||
3059 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3060 baseInternalFormat == GL_INTENSITY);
3061 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLubyte));
3062
3063 {
3064 /* general path */
3065 const GLuint *tempImage =
3066 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3067 srcWidth, srcHeight, srcDepth,
3068 srcFormat, srcType, srcAddr, srcPacking);
3069 const GLuint *src = tempImage;
3070 GLint img, row;
3071 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3072 if (!tempImage)
3073 return GL_FALSE;
3074 for (img = 0; img < srcDepth; img++) {
3075 GLubyte *dstRow = dstSlices[img];
3076 for (row = 0; row < srcHeight; row++) {
3077 GLubyte *dstTexel = (GLubyte *) dstRow;
3078 GLint i;
3079 if (is_unsigned) {
3080 for (i = 0; i < srcWidth * components; i++) {
3081 dstTexel[i] = (GLubyte) MIN2(src[i], 0xff);
3082 }
3083 } else {
3084 for (i = 0; i < srcWidth * components; i++) {
3085 dstTexel[i] = (GLubyte) CLAMP((GLint) src[i], 0, 0xff);
3086 }
3087 }
3088 dstRow += dstRowStride;
3089 src += srcWidth * components;
3090 }
3091 }
3092
3093 free((void *) tempImage);
3094 }
3095 return GL_TRUE;
3096 }
3097
3098
3099 /* non-normalized, unsigned int16 */
3100 static GLboolean
3101 _mesa_texstore_rgba_uint16(TEXSTORE_PARAMS)
3102 {
3103 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3104 GLint components = _mesa_components_in_format(baseFormat);
3105
3106 /* this forces alpha to 1 in make_temp_uint_image */
3107 if (dstFormat == MESA_FORMAT_RGBX_UINT16) {
3108 baseFormat = GL_RGBA;
3109 components = 4;
3110 }
3111
3112 ASSERT(dstFormat == MESA_FORMAT_R_UINT16 ||
3113 dstFormat == MESA_FORMAT_RG_UINT16 ||
3114 dstFormat == MESA_FORMAT_RGB_UINT16 ||
3115 dstFormat == MESA_FORMAT_RGBA_UINT16 ||
3116 dstFormat == MESA_FORMAT_A_UINT16 ||
3117 dstFormat == MESA_FORMAT_I_UINT16 ||
3118 dstFormat == MESA_FORMAT_L_UINT16 ||
3119 dstFormat == MESA_FORMAT_LA_UINT16 ||
3120 dstFormat == MESA_FORMAT_RGBX_UINT16);
3121 ASSERT(baseInternalFormat == GL_RGBA ||
3122 baseInternalFormat == GL_RGB ||
3123 baseInternalFormat == GL_RG ||
3124 baseInternalFormat == GL_RED ||
3125 baseInternalFormat == GL_ALPHA ||
3126 baseInternalFormat == GL_LUMINANCE ||
3127 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3128 baseInternalFormat == GL_INTENSITY);
3129 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLushort));
3130
3131 {
3132 /* general path */
3133 const GLuint *tempImage =
3134 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3135 srcWidth, srcHeight, srcDepth,
3136 srcFormat, srcType, srcAddr, srcPacking);
3137 const GLuint *src = tempImage;
3138 GLint img, row;
3139 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3140 if (!tempImage)
3141 return GL_FALSE;
3142 for (img = 0; img < srcDepth; img++) {
3143 GLubyte *dstRow = dstSlices[img];
3144 for (row = 0; row < srcHeight; row++) {
3145 GLushort *dstTexel = (GLushort *) dstRow;
3146 GLint i;
3147 if (is_unsigned) {
3148 for (i = 0; i < srcWidth * components; i++) {
3149 dstTexel[i] = (GLushort) MIN2(src[i], 0xffff);
3150 }
3151 } else {
3152 for (i = 0; i < srcWidth * components; i++) {
3153 dstTexel[i] = (GLushort) CLAMP((GLint) src[i], 0, 0xffff);
3154 }
3155 }
3156 dstRow += dstRowStride;
3157 src += srcWidth * components;
3158 }
3159 }
3160
3161 free((void *) tempImage);
3162 }
3163 return GL_TRUE;
3164 }
3165
3166
3167 /* non-normalized, unsigned int32 */
3168 static GLboolean
3169 _mesa_texstore_rgba_uint32(TEXSTORE_PARAMS)
3170 {
3171 GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3172 GLint components = _mesa_components_in_format(baseFormat);
3173
3174 /* this forces alpha to 1 in make_temp_uint_image */
3175 if (dstFormat == MESA_FORMAT_RGBX_UINT32) {
3176 baseFormat = GL_RGBA;
3177 components = 4;
3178 }
3179
3180 ASSERT(dstFormat == MESA_FORMAT_R_UINT32 ||
3181 dstFormat == MESA_FORMAT_RG_UINT32 ||
3182 dstFormat == MESA_FORMAT_RGB_UINT32 ||
3183 dstFormat == MESA_FORMAT_RGBA_UINT32 ||
3184 dstFormat == MESA_FORMAT_A_UINT32 ||
3185 dstFormat == MESA_FORMAT_I_UINT32 ||
3186 dstFormat == MESA_FORMAT_L_UINT32 ||
3187 dstFormat == MESA_FORMAT_LA_UINT32 ||
3188 dstFormat == MESA_FORMAT_RGBX_UINT32);
3189 ASSERT(baseInternalFormat == GL_RGBA ||
3190 baseInternalFormat == GL_RGB ||
3191 baseInternalFormat == GL_RG ||
3192 baseInternalFormat == GL_RED ||
3193 baseInternalFormat == GL_ALPHA ||
3194 baseInternalFormat == GL_LUMINANCE ||
3195 baseInternalFormat == GL_LUMINANCE_ALPHA ||
3196 baseInternalFormat == GL_INTENSITY);
3197 ASSERT(_mesa_get_format_bytes(dstFormat) == components * sizeof(GLuint));
3198
3199 {
3200 /* general path */
3201 const GLuint *tempImage =
3202 make_temp_uint_image(ctx, dims, baseInternalFormat, baseFormat,
3203 srcWidth, srcHeight, srcDepth,
3204 srcFormat, srcType, srcAddr, srcPacking);
3205 const GLuint *src = tempImage;
3206 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3207 GLint img, row;
3208 if (!tempImage)
3209 return GL_FALSE;
3210 for (img = 0; img < srcDepth; img++) {
3211 GLubyte *dstRow = dstSlices[img];
3212 for (row = 0; row < srcHeight; row++) {
3213 GLuint *dstTexel = (GLuint *) dstRow;
3214 GLint i;
3215 if (is_unsigned) {
3216 for (i = 0; i < srcWidth * components; i++) {
3217 dstTexel[i] = src[i];
3218 }
3219 } else {
3220 for (i = 0; i < srcWidth * components; i++) {
3221 dstTexel[i] = MAX2((GLint) src[i], 0);
3222 }
3223 }
3224 dstRow += dstRowStride;
3225 src += srcWidth * components;
3226 }
3227 }
3228
3229 free((void *) tempImage);
3230 }
3231 return GL_TRUE;
3232 }
3233
3234
3235 static GLboolean
3236 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
3237 {
3238 mesa_format newDstFormat;
3239 GLboolean k;
3240
3241 ASSERT(dstFormat == MESA_FORMAT_BGR_SRGB8);
3242
3243 /* reuse normal rgb texstore code */
3244 newDstFormat = MESA_FORMAT_BGR_UNORM8;
3245
3246 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
3247 newDstFormat,
3248 dstRowStride, dstSlices,
3249 srcWidth, srcHeight, srcDepth,
3250 srcFormat, srcType,
3251 srcAddr, srcPacking);
3252 return k;
3253 }
3254
3255
3256 static GLboolean
3257 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
3258 {
3259 mesa_format newDstFormat;
3260 GLboolean k;
3261
3262 ASSERT(dstFormat == MESA_FORMAT_A8B8G8R8_SRGB ||
3263 dstFormat == MESA_FORMAT_R8G8B8X8_SRGB ||
3264 dstFormat == MESA_FORMAT_R8G8B8A8_SRGB);
3265
3266 /* reuse normal rgba texstore code */
3267 if (dstFormat == MESA_FORMAT_A8B8G8R8_SRGB) {
3268 newDstFormat = MESA_FORMAT_A8B8G8R8_UNORM;
3269 }
3270 else if (dstFormat == MESA_FORMAT_R8G8B8A8_SRGB) {
3271 newDstFormat = MESA_FORMAT_R8G8B8A8_UNORM;
3272 }
3273 else if (dstFormat == MESA_FORMAT_R8G8B8X8_SRGB) {
3274 newDstFormat = MESA_FORMAT_R8G8B8X8_UNORM;
3275 }
3276 else {
3277 ASSERT(0);
3278 return GL_TRUE;
3279 }
3280
3281 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
3282 newDstFormat,
3283 dstRowStride, dstSlices,
3284 srcWidth, srcHeight, srcDepth,
3285 srcFormat, srcType,
3286 srcAddr, srcPacking);
3287 return k;
3288 }
3289
3290
3291 static GLboolean
3292 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
3293 {
3294 mesa_format newDstFormat;
3295 GLboolean k;
3296
3297 switch (dstFormat) {
3298 case MESA_FORMAT_B8G8R8A8_SRGB:
3299 newDstFormat = MESA_FORMAT_B8G8R8A8_UNORM;
3300 break;
3301 case MESA_FORMAT_B8G8R8X8_SRGB:
3302 newDstFormat = MESA_FORMAT_B8G8R8X8_UNORM;
3303 break;
3304 default:
3305 ASSERT(0);
3306 return GL_FALSE;
3307 }
3308
3309 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
3310 newDstFormat,
3311 dstRowStride, dstSlices,
3312 srcWidth, srcHeight, srcDepth,
3313 srcFormat, srcType,
3314 srcAddr, srcPacking);
3315 return k;
3316 }
3317
3318
3319 static GLboolean
3320 _mesa_texstore_sl8(TEXSTORE_PARAMS)
3321 {
3322 mesa_format newDstFormat;
3323 GLboolean k;
3324
3325 ASSERT(dstFormat == MESA_FORMAT_L_SRGB8);
3326
3327 newDstFormat = MESA_FORMAT_L_UNORM8;
3328
3329 /* _mesa_textore_a8 handles luminance8 too */
3330 k = _mesa_texstore_unorm8(ctx, dims, baseInternalFormat,
3331 newDstFormat,
3332 dstRowStride, dstSlices,
3333 srcWidth, srcHeight, srcDepth,
3334 srcFormat, srcType,
3335 srcAddr, srcPacking);
3336 return k;
3337 }
3338
3339
3340 static GLboolean
3341 _mesa_texstore_sla8(TEXSTORE_PARAMS)
3342 {
3343 mesa_format newDstFormat;
3344 GLboolean k;
3345
3346 ASSERT(dstFormat == MESA_FORMAT_L8A8_SRGB);
3347
3348 /* reuse normal luminance/alpha texstore code */
3349 newDstFormat = MESA_FORMAT_L8A8_UNORM;
3350
3351 k = _mesa_texstore_unorm88(ctx, dims, baseInternalFormat,
3352 newDstFormat,
3353 dstRowStride, dstSlices,
3354 srcWidth, srcHeight, srcDepth,
3355 srcFormat, srcType,
3356 srcAddr, srcPacking);
3357 return k;
3358 }
3359
3360 static GLboolean
3361 _mesa_texstore_rgb9_e5(TEXSTORE_PARAMS)
3362 {
3363 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3364
3365 ASSERT(dstFormat == MESA_FORMAT_R9G9B9E5_FLOAT);
3366 ASSERT(baseInternalFormat == GL_RGB);
3367
3368 {
3369 /* general path */
3370 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3371 baseInternalFormat,
3372 baseFormat,
3373 srcWidth, srcHeight, srcDepth,
3374 srcFormat, srcType, srcAddr,
3375 srcPacking,
3376 ctx->_ImageTransferState);
3377 const GLfloat *srcRow = tempImage;
3378 GLint img, row, col;
3379 if (!tempImage)
3380 return GL_FALSE;
3381 for (img = 0; img < srcDepth; img++) {
3382 GLubyte *dstRow = dstSlices[img];
3383 for (row = 0; row < srcHeight; row++) {
3384 GLuint *dstUI = (GLuint*)dstRow;
3385 for (col = 0; col < srcWidth; col++) {
3386 dstUI[col] = float3_to_rgb9e5(&srcRow[col * 3]);
3387 }
3388 dstRow += dstRowStride;
3389 srcRow += srcWidth * 3;
3390 }
3391 }
3392
3393 free((void *) tempImage);
3394 }
3395 return GL_TRUE;
3396 }
3397
3398 static GLboolean
3399 _mesa_texstore_r11_g11_b10f(TEXSTORE_PARAMS)
3400 {
3401 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3402
3403 ASSERT(dstFormat == MESA_FORMAT_R11G11B10_FLOAT);
3404 ASSERT(baseInternalFormat == GL_RGB);
3405
3406 {
3407 /* general path */
3408 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3409 baseInternalFormat,
3410 baseFormat,
3411 srcWidth, srcHeight, srcDepth,
3412 srcFormat, srcType, srcAddr,
3413 srcPacking,
3414 ctx->_ImageTransferState);
3415 const GLfloat *srcRow = tempImage;
3416 GLint img, row, col;
3417 if (!tempImage)
3418 return GL_FALSE;
3419 for (img = 0; img < srcDepth; img++) {
3420 GLubyte *dstRow = dstSlices[img];
3421 for (row = 0; row < srcHeight; row++) {
3422 GLuint *dstUI = (GLuint*)dstRow;
3423 for (col = 0; col < srcWidth; col++) {
3424 dstUI[col] = float3_to_r11g11b10f(&srcRow[col * 3]);
3425 }
3426 dstRow += dstRowStride;
3427 srcRow += srcWidth * 3;
3428 }
3429 }
3430
3431 free((void *) tempImage);
3432 }
3433 return GL_TRUE;
3434 }
3435
3436
3437 static GLboolean
3438 _mesa_texstore_z32f_x24s8(TEXSTORE_PARAMS)
3439 {
3440 ASSERT(dstFormat == MESA_FORMAT_Z32_FLOAT_S8X24_UINT);
3441 ASSERT(srcFormat == GL_DEPTH_STENCIL ||
3442 srcFormat == GL_DEPTH_COMPONENT ||
3443 srcFormat == GL_STENCIL_INDEX);
3444 ASSERT(srcFormat != GL_DEPTH_STENCIL ||
3445 srcType == GL_FLOAT_32_UNSIGNED_INT_24_8_REV);
3446
3447 if (srcFormat == GL_DEPTH_COMPONENT ||
3448 srcFormat == GL_STENCIL_INDEX) {
3449 GLint img, row;
3450 const GLint srcRowStride
3451 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
3452 / sizeof(uint64_t);
3453
3454 /* In case we only upload depth we need to preserve the stencil */
3455 for (img = 0; img < srcDepth; img++) {
3456 uint64_t *dstRow = (uint64_t *) dstSlices[img];
3457 const uint64_t *src
3458 = (const uint64_t *) _mesa_image_address(dims, srcPacking, srcAddr,
3459 srcWidth, srcHeight,
3460 srcFormat, srcType,
3461 img, 0, 0);
3462 for (row = 0; row < srcHeight; row++) {
3463 /* The unpack functions with:
3464 * dstType = GL_FLOAT_32_UNSIGNED_INT_24_8_REV
3465 * only write their own dword, so the other dword (stencil
3466 * or depth) is preserved. */
3467 if (srcFormat != GL_STENCIL_INDEX)
3468 _mesa_unpack_depth_span(ctx, srcWidth,
3469 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3470 dstRow, /* dst addr */
3471 ~0U, srcType, src, srcPacking);
3472
3473 if (srcFormat != GL_DEPTH_COMPONENT)
3474 _mesa_unpack_stencil_span(ctx, srcWidth,
3475 GL_FLOAT_32_UNSIGNED_INT_24_8_REV, /* dst type */
3476 dstRow, /* dst addr */
3477 srcType, src, srcPacking,
3478 ctx->_ImageTransferState);
3479
3480 src += srcRowStride;
3481 dstRow += dstRowStride / sizeof(uint64_t);
3482 }
3483 }
3484 }
3485 return GL_TRUE;
3486 }
3487
3488 static GLboolean
3489 _mesa_texstore_argb2101010_uint(TEXSTORE_PARAMS)
3490 {
3491 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3492
3493 ASSERT(dstFormat == MESA_FORMAT_B10G10R10A2_UINT);
3494 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3495
3496 {
3497 /* general path */
3498 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3499 baseInternalFormat,
3500 baseFormat,
3501 srcWidth, srcHeight,
3502 srcDepth, srcFormat,
3503 srcType, srcAddr,
3504 srcPacking);
3505 const GLuint *src = tempImage;
3506 GLint img, row, col;
3507 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3508 if (!tempImage)
3509 return GL_FALSE;
3510 for (img = 0; img < srcDepth; img++) {
3511 GLubyte *dstRow = dstSlices[img];
3512
3513 for (row = 0; row < srcHeight; row++) {
3514 GLuint *dstUI = (GLuint *) dstRow;
3515 if (is_unsigned) {
3516 for (col = 0; col < srcWidth; col++) {
3517 GLushort a,r,g,b;
3518 r = MIN2(src[RCOMP], 0x3ff);
3519 g = MIN2(src[GCOMP], 0x3ff);
3520 b = MIN2(src[BCOMP], 0x3ff);
3521 a = MIN2(src[ACOMP], 0x003);
3522 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3523 src += 4;
3524 }
3525 } else {
3526 for (col = 0; col < srcWidth; col++) {
3527 GLushort a,r,g,b;
3528 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
3529 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
3530 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
3531 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
3532 dstUI[col] = (a << 30) | (r << 20) | (g << 10) | (b);
3533 src += 4;
3534 }
3535 }
3536 dstRow += dstRowStride;
3537 }
3538 }
3539 free((void *) tempImage);
3540 }
3541 return GL_TRUE;
3542 }
3543
3544 static GLboolean
3545 _mesa_texstore_abgr2101010_uint(TEXSTORE_PARAMS)
3546 {
3547 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3548
3549 ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UINT);
3550 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3551
3552 {
3553 /* general path */
3554 const GLuint *tempImage = make_temp_uint_image(ctx, dims,
3555 baseInternalFormat,
3556 baseFormat,
3557 srcWidth, srcHeight,
3558 srcDepth, srcFormat,
3559 srcType, srcAddr,
3560 srcPacking);
3561 const GLuint *src = tempImage;
3562 GLint img, row, col;
3563 GLboolean is_unsigned = _mesa_is_type_unsigned(srcType);
3564 if (!tempImage)
3565 return GL_FALSE;
3566 for (img = 0; img < srcDepth; img++) {
3567 GLubyte *dstRow = dstSlices[img];
3568
3569 for (row = 0; row < srcHeight; row++) {
3570 GLuint *dstUI = (GLuint *) dstRow;
3571 if (is_unsigned) {
3572 for (col = 0; col < srcWidth; col++) {
3573 GLushort a,r,g,b;
3574 r = MIN2(src[RCOMP], 0x3ff);
3575 g = MIN2(src[GCOMP], 0x3ff);
3576 b = MIN2(src[BCOMP], 0x3ff);
3577 a = MIN2(src[ACOMP], 0x003);
3578 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
3579 src += 4;
3580 }
3581 } else {
3582 for (col = 0; col < srcWidth; col++) {
3583 GLushort a,r,g,b;
3584 r = CLAMP((GLint) src[RCOMP], 0, 0x3ff);
3585 g = CLAMP((GLint) src[GCOMP], 0, 0x3ff);
3586 b = CLAMP((GLint) src[BCOMP], 0, 0x3ff);
3587 a = CLAMP((GLint) src[ACOMP], 0, 0x003);
3588 dstUI[col] = (a << 30) | (b << 20) | (g << 10) | (r);
3589 src += 4;
3590 }
3591 }
3592 dstRow += dstRowStride;
3593 }
3594 }
3595 free((void *) tempImage);
3596 }
3597 return GL_TRUE;
3598 }
3599
3600 static GLboolean
3601 _mesa_texstore_abgr2101010(TEXSTORE_PARAMS)
3602 {
3603 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
3604
3605 ASSERT(dstFormat == MESA_FORMAT_R10G10B10A2_UNORM);
3606 ASSERT(_mesa_get_format_bytes(dstFormat) == 4);
3607
3608 {
3609 /* general path */
3610 const GLfloat *tempImage = _mesa_make_temp_float_image(ctx, dims,
3611 baseInternalFormat,
3612 baseFormat,
3613 srcWidth, srcHeight, srcDepth,
3614 srcFormat, srcType, srcAddr,
3615 srcPacking,
3616 ctx->_ImageTransferState);
3617 const GLfloat *src = tempImage;
3618 GLint img, row, col;
3619 if (!tempImage)
3620 return GL_FALSE;
3621 for (img = 0; img < srcDepth; img++) {
3622 GLubyte *dstRow = dstSlices[img];
3623
3624 for (row = 0; row < srcHeight; row++) {
3625 GLuint *dstUI = (GLuint *) dstRow;
3626 for (col = 0; col < srcWidth; col++) {
3627 GLushort a,r,g,b;
3628
3629 UNCLAMPED_FLOAT_TO_USHORT(a, src[ACOMP]);
3630 UNCLAMPED_FLOAT_TO_USHORT(r, src[RCOMP]);
3631 UNCLAMPED_FLOAT_TO_USHORT(g, src[GCOMP]);
3632 UNCLAMPED_FLOAT_TO_USHORT(b, src[BCOMP]);
3633 dstUI[col] = PACK_COLOR_2101010_US(a, b, g, r);
3634 src += 4;
3635 }
3636 dstRow += dstRowStride;
3637 }
3638 }
3639 free((void *) tempImage);
3640 }
3641 return GL_TRUE;
3642 }
3643
3644 static GLboolean
3645 _mesa_texstore_null(TEXSTORE_PARAMS)
3646 {
3647 (void) ctx; (void) dims;
3648 (void) baseInternalFormat;
3649 (void) dstFormat;
3650 (void) dstRowStride; (void) dstSlices,
3651 (void) srcWidth; (void) srcHeight; (void) srcDepth;
3652 (void) srcFormat; (void) srcType;
3653 (void) srcAddr;
3654 (void) srcPacking;
3655
3656 /* should never happen */
3657 _mesa_problem(NULL, "_mesa_texstore_null() is called");
3658 return GL_FALSE;
3659 }
3660
3661
3662 /**
3663 * Return the StoreTexImageFunc pointer to store an image in the given format.
3664 */
3665 static StoreTexImageFunc
3666 _mesa_get_texstore_func(mesa_format format)
3667 {
3668 static StoreTexImageFunc table[MESA_FORMAT_COUNT];
3669 static GLboolean initialized = GL_FALSE;
3670
3671 if (!initialized) {
3672 table[MESA_FORMAT_NONE] = _mesa_texstore_null;
3673
3674 table[MESA_FORMAT_A8B8G8R8_UNORM] = _mesa_texstore_rgba8888;
3675 table[MESA_FORMAT_R8G8B8A8_UNORM] = _mesa_texstore_rgba8888;
3676 table[MESA_FORMAT_B8G8R8A8_UNORM] = _mesa_texstore_argb8888;
3677 table[MESA_FORMAT_A8R8G8B8_UNORM] = _mesa_texstore_argb8888;
3678 table[MESA_FORMAT_X8B8G8R8_UNORM] = _mesa_texstore_rgba8888;
3679 table[MESA_FORMAT_R8G8B8X8_UNORM] = _mesa_texstore_rgba8888;
3680 table[MESA_FORMAT_B8G8R8X8_UNORM] = _mesa_texstore_argb8888;
3681 table[MESA_FORMAT_X8R8G8B8_UNORM] = _mesa_texstore_argb8888;
3682 table[MESA_FORMAT_BGR_UNORM8] = _mesa_texstore_rgb888;
3683 table[MESA_FORMAT_RGB_UNORM8] = _mesa_texstore_bgr888;
3684 table[MESA_FORMAT_B5G6R5_UNORM] = _mesa_texstore_rgb565;
3685 table[MESA_FORMAT_R5G6B5_UNORM] = _mesa_texstore_rgb565;
3686 table[MESA_FORMAT_B4G4R4A4_UNORM] = store_ubyte_texture;
3687 table[MESA_FORMAT_A4R4G4B4_UNORM] = store_ubyte_texture;
3688 table[MESA_FORMAT_A1B5G5R5_UNORM] = store_ubyte_texture;
3689 table[MESA_FORMAT_B5G5R5A1_UNORM] = store_ubyte_texture;
3690 table[MESA_FORMAT_A1R5G5B5_UNORM] = store_ubyte_texture;
3691 table[MESA_FORMAT_L4A4_UNORM] = _mesa_texstore_unorm44;
3692 table[MESA_FORMAT_L8A8_UNORM] = _mesa_texstore_unorm88;
3693 table[MESA_FORMAT_A8L8_UNORM] = _mesa_texstore_unorm88;
3694 table[MESA_FORMAT_L16A16_UNORM] = _mesa_texstore_unorm1616;
3695 table[MESA_FORMAT_A16L16_UNORM] = _mesa_texstore_unorm1616;
3696 table[MESA_FORMAT_B2G3R3_UNORM] = store_ubyte_texture;
3697 table[MESA_FORMAT_A_UNORM8] = _mesa_texstore_unorm8;
3698 table[MESA_FORMAT_A_UNORM16] = _mesa_texstore_unorm16;
3699 table[MESA_FORMAT_L_UNORM8] = _mesa_texstore_unorm8;
3700 table[MESA_FORMAT_L_UNORM16] = _mesa_texstore_unorm16;
3701 table[MESA_FORMAT_I_UNORM8] = _mesa_texstore_unorm8;
3702 table[MESA_FORMAT_I_UNORM16] = _mesa_texstore_unorm16;
3703 table[MESA_FORMAT_YCBCR] = _mesa_texstore_ycbcr;
3704 table[MESA_FORMAT_YCBCR_REV] = _mesa_texstore_ycbcr;
3705 table[MESA_FORMAT_R_UNORM8] = _mesa_texstore_unorm8;
3706 table[MESA_FORMAT_R8G8_UNORM] = _mesa_texstore_unorm88;
3707 table[MESA_FORMAT_G8R8_UNORM] = _mesa_texstore_unorm88;
3708 table[MESA_FORMAT_R_UNORM16] = _mesa_texstore_unorm16;
3709 table[MESA_FORMAT_R16G16_UNORM] = _mesa_texstore_unorm1616;
3710 table[MESA_FORMAT_G16R16_UNORM] = _mesa_texstore_unorm1616;
3711 table[MESA_FORMAT_B10G10R10A2_UNORM] = _mesa_texstore_argb2101010;
3712 table[MESA_FORMAT_S8_UINT_Z24_UNORM] = _mesa_texstore_z24_s8;
3713 table[MESA_FORMAT_Z24_UNORM_S8_UINT] = _mesa_texstore_s8_z24;
3714 table[MESA_FORMAT_Z_UNORM16] = _mesa_texstore_z16;
3715 table[MESA_FORMAT_Z24_UNORM_X8_UINT] = _mesa_texstore_x8_z24;
3716 table[MESA_FORMAT_X8_UINT_Z24_UNORM] = _mesa_texstore_z24_x8;
3717 table[MESA_FORMAT_Z_UNORM32] = _mesa_texstore_z32;
3718 table[MESA_FORMAT_S_UINT8] = _mesa_texstore_s8;
3719 table[MESA_FORMAT_BGR_SRGB8] = _mesa_texstore_srgb8;
3720 table[MESA_FORMAT_A8B8G8R8_SRGB] = _mesa_texstore_srgba8;
3721 table[MESA_FORMAT_B8G8R8A8_SRGB] = _mesa_texstore_sargb8;
3722 table[MESA_FORMAT_L_SRGB8] = _mesa_texstore_sl8;
3723 table[MESA_FORMAT_L8A8_SRGB] = _mesa_texstore_sla8;
3724 table[MESA_FORMAT_SRGB_DXT1] = _mesa_texstore_rgb_dxt1;
3725 table[MESA_FORMAT_SRGBA_DXT1] = _mesa_texstore_rgba_dxt1;
3726 table[MESA_FORMAT_SRGBA_DXT3] = _mesa_texstore_rgba_dxt3;
3727 table[MESA_FORMAT_SRGBA_DXT5] = _mesa_texstore_rgba_dxt5;
3728 table[MESA_FORMAT_RGB_FXT1] = _mesa_texstore_rgb_fxt1;
3729 table[MESA_FORMAT_RGBA_FXT1] = _mesa_texstore_rgba_fxt1;
3730 table[MESA_FORMAT_RGB_DXT1] = _mesa_texstore_rgb_dxt1;
3731 table[MESA_FORMAT_RGBA_DXT1] = _mesa_texstore_rgba_dxt1;
3732 table[MESA_FORMAT_RGBA_DXT3] = _mesa_texstore_rgba_dxt3;
3733 table[MESA_FORMAT_RGBA_DXT5] = _mesa_texstore_rgba_dxt5;
3734 table[MESA_FORMAT_RGBA_FLOAT32] = _mesa_texstore_rgba_float32;
3735 table[MESA_FORMAT_RGBA_FLOAT16] = _mesa_texstore_rgba_float16;
3736 table[MESA_FORMAT_RGB_FLOAT32] = _mesa_texstore_rgba_float32;
3737 table[MESA_FORMAT_RGB_FLOAT16] = _mesa_texstore_rgba_float16;
3738 table[MESA_FORMAT_A_FLOAT32] = _mesa_texstore_rgba_float32;
3739 table[MESA_FORMAT_A_FLOAT16] = _mesa_texstore_rgba_float16;
3740 table[MESA_FORMAT_L_FLOAT32] = _mesa_texstore_rgba_float32;
3741 table[MESA_FORMAT_L_FLOAT16] = _mesa_texstore_rgba_float16;
3742 table[MESA_FORMAT_LA_FLOAT32] = _mesa_texstore_rgba_float32;
3743 table[MESA_FORMAT_LA_FLOAT16] = _mesa_texstore_rgba_float16;
3744 table[MESA_FORMAT_I_FLOAT32] = _mesa_texstore_rgba_float32;
3745 table[MESA_FORMAT_I_FLOAT16] = _mesa_texstore_rgba_float16;
3746 table[MESA_FORMAT_R_FLOAT32] = _mesa_texstore_rgba_float32;
3747 table[MESA_FORMAT_R_FLOAT16] = _mesa_texstore_rgba_float16;
3748 table[MESA_FORMAT_RG_FLOAT32] = _mesa_texstore_rgba_float32;
3749 table[MESA_FORMAT_RG_FLOAT16] = _mesa_texstore_rgba_float16;
3750 table[MESA_FORMAT_DUDV8] = _mesa_texstore_dudv8;
3751 table[MESA_FORMAT_R_SNORM8] = _mesa_texstore_snorm8;
3752 table[MESA_FORMAT_R8G8_SNORM] = _mesa_texstore_snorm88;
3753 table[MESA_FORMAT_X8B8G8R8_SNORM] = _mesa_texstore_signed_rgbx8888;
3754 table[MESA_FORMAT_A8B8G8R8_SNORM] = _mesa_texstore_signed_rgba8888;
3755 table[MESA_FORMAT_R8G8B8A8_SNORM] = _mesa_texstore_signed_rgba8888;
3756 table[MESA_FORMAT_R_SNORM16] = _mesa_texstore_snorm16;
3757 table[MESA_FORMAT_R16G16_SNORM] = _mesa_texstore_snorm1616;
3758 table[MESA_FORMAT_RGB_SNORM16] = _mesa_texstore_signed_rgba_16;
3759 table[MESA_FORMAT_RGBA_SNORM16] = _mesa_texstore_signed_rgba_16;
3760 table[MESA_FORMAT_RGBA_UNORM16] = _mesa_texstore_rgba_16;
3761 table[MESA_FORMAT_R_RGTC1_UNORM] = _mesa_texstore_red_rgtc1;
3762 table[MESA_FORMAT_R_RGTC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
3763 table[MESA_FORMAT_RG_RGTC2_UNORM] = _mesa_texstore_rg_rgtc2;
3764 table[MESA_FORMAT_RG_RGTC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
3765 table[MESA_FORMAT_L_LATC1_UNORM] = _mesa_texstore_red_rgtc1;
3766 table[MESA_FORMAT_L_LATC1_SNORM] = _mesa_texstore_signed_red_rgtc1;
3767 table[MESA_FORMAT_LA_LATC2_UNORM] = _mesa_texstore_rg_rgtc2;
3768 table[MESA_FORMAT_LA_LATC2_SNORM] = _mesa_texstore_signed_rg_rgtc2;
3769 table[MESA_FORMAT_ETC1_RGB8] = _mesa_texstore_etc1_rgb8;
3770 table[MESA_FORMAT_ETC2_RGB8] = _mesa_texstore_etc2_rgb8;
3771 table[MESA_FORMAT_ETC2_SRGB8] = _mesa_texstore_etc2_srgb8;
3772 table[MESA_FORMAT_ETC2_RGBA8_EAC] = _mesa_texstore_etc2_rgba8_eac;
3773 table[MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC] = _mesa_texstore_etc2_srgb8_alpha8_eac;
3774 table[MESA_FORMAT_ETC2_R11_EAC] = _mesa_texstore_etc2_r11_eac;
3775 table[MESA_FORMAT_ETC2_RG11_EAC] = _mesa_texstore_etc2_rg11_eac;
3776 table[MESA_FORMAT_ETC2_SIGNED_R11_EAC] = _mesa_texstore_etc2_signed_r11_eac;
3777 table[MESA_FORMAT_ETC2_SIGNED_RG11_EAC] = _mesa_texstore_etc2_signed_rg11_eac;
3778 table[MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1] =
3779 _mesa_texstore_etc2_rgb8_punchthrough_alpha1;
3780 table[MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1] =
3781 _mesa_texstore_etc2_srgb8_punchthrough_alpha1;
3782 table[MESA_FORMAT_A_SNORM8] = _mesa_texstore_snorm8;
3783 table[MESA_FORMAT_L_SNORM8] = _mesa_texstore_snorm8;
3784 table[MESA_FORMAT_L8A8_SNORM] = _mesa_texstore_snorm88;
3785 table[MESA_FORMAT_I_SNORM8] = _mesa_texstore_snorm8;
3786 table[MESA_FORMAT_A_SNORM16] = _mesa_texstore_snorm16;
3787 table[MESA_FORMAT_L_SNORM16] = _mesa_texstore_snorm16;
3788 table[MESA_FORMAT_LA_SNORM16] = _mesa_texstore_snorm1616;
3789 table[MESA_FORMAT_I_SNORM16] = _mesa_texstore_snorm16;
3790 table[MESA_FORMAT_R9G9B9E5_FLOAT] = _mesa_texstore_rgb9_e5;
3791 table[MESA_FORMAT_R11G11B10_FLOAT] = _mesa_texstore_r11_g11_b10f;
3792 table[MESA_FORMAT_Z_FLOAT32] = _mesa_texstore_z32;
3793 table[MESA_FORMAT_Z32_FLOAT_S8X24_UINT] = _mesa_texstore_z32f_x24s8;
3794
3795 table[MESA_FORMAT_A_UINT8] = _mesa_texstore_rgba_uint8;
3796 table[MESA_FORMAT_A_UINT16] = _mesa_texstore_rgba_uint16;
3797 table[MESA_FORMAT_A_UINT32] = _mesa_texstore_rgba_uint32;
3798 table[MESA_FORMAT_A_SINT8] = _mesa_texstore_rgba_int8;
3799 table[MESA_FORMAT_A_SINT16] = _mesa_texstore_rgba_int16;
3800 table[MESA_FORMAT_A_SINT32] = _mesa_texstore_rgba_int32;
3801
3802 table[MESA_FORMAT_I_UINT8] = _mesa_texstore_rgba_uint8;
3803 table[MESA_FORMAT_I_UINT16] = _mesa_texstore_rgba_uint16;
3804 table[MESA_FORMAT_I_UINT32] = _mesa_texstore_rgba_uint32;
3805 table[MESA_FORMAT_I_SINT8] = _mesa_texstore_rgba_int8;
3806 table[MESA_FORMAT_I_SINT16] = _mesa_texstore_rgba_int16;
3807 table[MESA_FORMAT_I_SINT32] = _mesa_texstore_rgba_int32;
3808
3809 table[MESA_FORMAT_L_UINT8] = _mesa_texstore_rgba_uint8;
3810 table[MESA_FORMAT_L_UINT16] = _mesa_texstore_rgba_uint16;
3811 table[MESA_FORMAT_L_UINT32] = _mesa_texstore_rgba_uint32;
3812 table[MESA_FORMAT_L_SINT8] = _mesa_texstore_rgba_int8;
3813 table[MESA_FORMAT_L_SINT16] = _mesa_texstore_rgba_int16;
3814 table[MESA_FORMAT_L_SINT32] = _mesa_texstore_rgba_int32;
3815
3816 table[MESA_FORMAT_LA_UINT8] = _mesa_texstore_rgba_uint8;
3817 table[MESA_FORMAT_LA_UINT16] = _mesa_texstore_rgba_uint16;
3818 table[MESA_FORMAT_LA_UINT32] = _mesa_texstore_rgba_uint32;
3819 table[MESA_FORMAT_LA_SINT8] = _mesa_texstore_rgba_int8;
3820 table[MESA_FORMAT_LA_SINT16] = _mesa_texstore_rgba_int16;
3821 table[MESA_FORMAT_LA_SINT32] = _mesa_texstore_rgba_int32;
3822
3823 table[MESA_FORMAT_R_SINT8] = _mesa_texstore_rgba_int8;
3824 table[MESA_FORMAT_RG_SINT8] = _mesa_texstore_rgba_int8;
3825 table[MESA_FORMAT_RGB_SINT8] = _mesa_texstore_rgba_int8;
3826 table[MESA_FORMAT_RGBA_SINT8] = _mesa_texstore_rgba_int8;
3827 table[MESA_FORMAT_R_SINT16] = _mesa_texstore_rgba_int16;
3828 table[MESA_FORMAT_RG_SINT16] = _mesa_texstore_rgba_int16;
3829 table[MESA_FORMAT_RGB_SINT16] = _mesa_texstore_rgba_int16;
3830 table[MESA_FORMAT_RGBA_SINT16] = _mesa_texstore_rgba_int16;
3831 table[MESA_FORMAT_R_SINT32] = _mesa_texstore_rgba_int32;
3832 table[MESA_FORMAT_RG_SINT32] = _mesa_texstore_rgba_int32;
3833 table[MESA_FORMAT_RGB_SINT32] = _mesa_texstore_rgba_int32;
3834 table[MESA_FORMAT_RGBA_SINT32] = _mesa_texstore_rgba_int32;
3835
3836 table[MESA_FORMAT_R_UINT8] = _mesa_texstore_rgba_uint8;
3837 table[MESA_FORMAT_RG_UINT8] = _mesa_texstore_rgba_uint8;
3838 table[MESA_FORMAT_RGB_UINT8] = _mesa_texstore_rgba_uint8;
3839 table[MESA_FORMAT_RGBA_UINT8] = _mesa_texstore_rgba_uint8;
3840 table[MESA_FORMAT_R_UINT16] = _mesa_texstore_rgba_uint16;
3841 table[MESA_FORMAT_RG_UINT16] = _mesa_texstore_rgba_uint16;
3842 table[MESA_FORMAT_RGB_UINT16] = _mesa_texstore_rgba_uint16;
3843 table[MESA_FORMAT_RGBA_UINT16] = _mesa_texstore_rgba_uint16;
3844 table[MESA_FORMAT_R_UINT32] = _mesa_texstore_rgba_uint32;
3845 table[MESA_FORMAT_RG_UINT32] = _mesa_texstore_rgba_uint32;
3846 table[MESA_FORMAT_RGB_UINT32] = _mesa_texstore_rgba_uint32;
3847 table[MESA_FORMAT_RGBA_UINT32] = _mesa_texstore_rgba_uint32;
3848
3849 table[MESA_FORMAT_B10G10R10A2_UINT] = _mesa_texstore_argb2101010_uint;
3850 table[MESA_FORMAT_R10G10B10A2_UINT] = _mesa_texstore_abgr2101010_uint;
3851
3852 table[MESA_FORMAT_B4G4R4X4_UNORM] = store_ubyte_texture;
3853 table[MESA_FORMAT_B5G5R5X1_UNORM] = store_ubyte_texture;
3854 table[MESA_FORMAT_R8G8B8X8_SNORM] = _mesa_texstore_signed_rgbx8888;
3855 table[MESA_FORMAT_R8G8B8X8_SRGB] = _mesa_texstore_srgba8;
3856 table[MESA_FORMAT_R8G8B8A8_SRGB] = _mesa_texstore_srgba8;
3857 table[MESA_FORMAT_RGBX_UINT8] = _mesa_texstore_rgba_uint8;
3858 table[MESA_FORMAT_RGBX_SINT8] = _mesa_texstore_rgba_int8;
3859 table[MESA_FORMAT_B10G10R10X2_UNORM] = _mesa_texstore_argb2101010;
3860 table[MESA_FORMAT_RGBX_UNORM16] = _mesa_texstore_rgba_16;
3861 table[MESA_FORMAT_RGBX_SNORM16] = _mesa_texstore_signed_rgba_16;
3862 table[MESA_FORMAT_RGBX_FLOAT16] = _mesa_texstore_rgba_float16;
3863 table[MESA_FORMAT_RGBX_UINT16] = _mesa_texstore_rgba_uint16;
3864 table[MESA_FORMAT_RGBX_SINT16] = _mesa_texstore_rgba_int16;
3865 table[MESA_FORMAT_RGBX_FLOAT32] = _mesa_texstore_rgba_float32;
3866 table[MESA_FORMAT_RGBX_UINT32] = _mesa_texstore_rgba_uint32;
3867 table[MESA_FORMAT_RGBX_SINT32] = _mesa_texstore_rgba_int32;
3868
3869 table[MESA_FORMAT_R10G10B10A2_UNORM] = _mesa_texstore_abgr2101010;
3870
3871 table[MESA_FORMAT_G8R8_SNORM] = _mesa_texstore_snorm88;
3872 table[MESA_FORMAT_G16R16_SNORM] = _mesa_texstore_snorm1616;
3873
3874 table[MESA_FORMAT_B8G8R8X8_SRGB] = _mesa_texstore_sargb8;
3875
3876 initialized = GL_TRUE;
3877 }
3878
3879 ASSERT(table[format]);
3880 return table[format];
3881 }
3882
3883
3884 GLboolean
3885 _mesa_texstore_needs_transfer_ops(struct gl_context *ctx,
3886 GLenum baseInternalFormat,
3887 mesa_format dstFormat)
3888 {
3889 GLenum dstType;
3890
3891 /* There are different rules depending on the base format. */
3892 switch (baseInternalFormat) {
3893 case GL_DEPTH_COMPONENT:
3894 case GL_DEPTH_STENCIL:
3895 return ctx->Pixel.DepthScale != 1.0f ||
3896 ctx->Pixel.DepthBias != 0.0f;
3897
3898 case GL_STENCIL_INDEX:
3899 return GL_FALSE;
3900
3901 default:
3902 /* Color formats.
3903 * Pixel transfer ops (scale, bias, table lookup) do not apply
3904 * to integer formats.
3905 */
3906 dstType = _mesa_get_format_datatype(dstFormat);
3907
3908 return dstType != GL_INT && dstType != GL_UNSIGNED_INT &&
3909 ctx->_ImageTransferState;
3910 }
3911 }
3912
3913
3914 GLboolean
3915 _mesa_texstore_can_use_memcpy(struct gl_context *ctx,
3916 GLenum baseInternalFormat, mesa_format dstFormat,
3917 GLenum srcFormat, GLenum srcType,
3918 const struct gl_pixelstore_attrib *srcPacking)
3919 {
3920 if (_mesa_texstore_needs_transfer_ops(ctx, baseInternalFormat, dstFormat)) {
3921 return GL_FALSE;
3922 }
3923
3924 /* The base internal format and the base Mesa format must match. */
3925 if (baseInternalFormat != _mesa_get_format_base_format(dstFormat)) {
3926 return GL_FALSE;
3927 }
3928
3929 /* The Mesa format must match the input format and type. */
3930 if (!_mesa_format_matches_format_and_type(dstFormat, srcFormat, srcType,
3931 srcPacking->SwapBytes)) {
3932 return GL_FALSE;
3933 }
3934
3935 return GL_TRUE;
3936 }
3937
3938 static GLboolean
3939 _mesa_texstore_memcpy(TEXSTORE_PARAMS)
3940 {
3941 if (!_mesa_texstore_can_use_memcpy(ctx, baseInternalFormat, dstFormat,
3942 srcFormat, srcType, srcPacking)) {
3943 return GL_FALSE;
3944 }
3945
3946 memcpy_texture(ctx, dims,
3947 dstFormat,
3948 dstRowStride, dstSlices,
3949 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
3950 srcAddr, srcPacking);
3951 return GL_TRUE;
3952 }
3953
3954
3955 /**
3956 * Store user data into texture memory.
3957 * Called via glTex[Sub]Image1/2/3D()
3958 * \return GL_TRUE for success, GL_FALSE for failure (out of memory).
3959 */
3960 GLboolean
3961 _mesa_texstore(TEXSTORE_PARAMS)
3962 {
3963 StoreTexImageFunc storeImage;
3964 GLboolean success;
3965
3966 if (_mesa_texstore_memcpy(ctx, dims, baseInternalFormat,
3967 dstFormat,
3968 dstRowStride, dstSlices,
3969 srcWidth, srcHeight, srcDepth,
3970 srcFormat, srcType, srcAddr, srcPacking)) {
3971 return GL_TRUE;
3972 }
3973
3974 storeImage = _mesa_get_texstore_func(dstFormat);
3975
3976 success = storeImage(ctx, dims, baseInternalFormat,
3977 dstFormat,
3978 dstRowStride, dstSlices,
3979 srcWidth, srcHeight, srcDepth,
3980 srcFormat, srcType, srcAddr, srcPacking);
3981 return success;
3982 }
3983
3984
3985 /**
3986 * Normally, we'll only _write_ texel data to a texture when we map it.
3987 * But if the user is providing depth or stencil values and the texture
3988 * image is a combined depth/stencil format, we'll actually read from
3989 * the texture buffer too (in order to insert the depth or stencil values.
3990 * \param userFormat the user-provided image format
3991 * \param texFormat the destination texture format
3992 */
3993 static GLbitfield
3994 get_read_write_mode(GLenum userFormat, mesa_format texFormat)
3995 {
3996 if ((userFormat == GL_STENCIL_INDEX || userFormat == GL_DEPTH_COMPONENT)
3997 && _mesa_get_format_base_format(texFormat) == GL_DEPTH_STENCIL)
3998 return GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
3999 else
4000 return GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT;
4001 }
4002
4003
4004 /**
4005 * Helper function for storing 1D, 2D, 3D whole and subimages into texture
4006 * memory.
4007 * The source of the image data may be user memory or a PBO. In the later
4008 * case, we'll map the PBO, copy from it, then unmap it.
4009 */
4010 static void
4011 store_texsubimage(struct gl_context *ctx,
4012 struct gl_texture_image *texImage,
4013 GLint xoffset, GLint yoffset, GLint zoffset,
4014 GLint width, GLint height, GLint depth,
4015 GLenum format, GLenum type, const GLvoid *pixels,
4016 const struct gl_pixelstore_attrib *packing,
4017 const char *caller)
4018
4019 {
4020 const GLbitfield mapMode = get_read_write_mode(format, texImage->TexFormat);
4021 const GLenum target = texImage->TexObject->Target;
4022 GLboolean success = GL_FALSE;
4023 GLuint dims, slice, numSlices = 1, sliceOffset = 0;
4024 GLint srcImageStride = 0;
4025 const GLubyte *src;
4026
4027 assert(xoffset + width <= texImage->Width);
4028 assert(yoffset + height <= texImage->Height);
4029 assert(zoffset + depth <= texImage->Depth);
4030
4031 switch (target) {
4032 case GL_TEXTURE_1D:
4033 dims = 1;
4034 break;
4035 case GL_TEXTURE_2D_ARRAY:
4036 case GL_TEXTURE_CUBE_MAP_ARRAY:
4037 case GL_TEXTURE_3D:
4038 dims = 3;
4039 break;
4040 default:
4041 dims = 2;
4042 }
4043
4044 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4045 src = (const GLubyte *)
4046 _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
4047 format, type, pixels, packing, caller);
4048 if (!src)
4049 return;
4050
4051 /* compute slice info (and do some sanity checks) */
4052 switch (target) {
4053 case GL_TEXTURE_2D:
4054 case GL_TEXTURE_RECTANGLE:
4055 case GL_TEXTURE_CUBE_MAP:
4056 case GL_TEXTURE_EXTERNAL_OES:
4057 /* one image slice, nothing special needs to be done */
4058 break;
4059 case GL_TEXTURE_1D:
4060 assert(height == 1);
4061 assert(depth == 1);
4062 assert(yoffset == 0);
4063 assert(zoffset == 0);
4064 break;
4065 case GL_TEXTURE_1D_ARRAY:
4066 assert(depth == 1);
4067 assert(zoffset == 0);
4068 numSlices = height;
4069 sliceOffset = yoffset;
4070 height = 1;
4071 yoffset = 0;
4072 srcImageStride = _mesa_image_row_stride(packing, width, format, type);
4073 break;
4074 case GL_TEXTURE_2D_ARRAY:
4075 numSlices = depth;
4076 sliceOffset = zoffset;
4077 depth = 1;
4078 zoffset = 0;
4079 srcImageStride = _mesa_image_image_stride(packing, width, height,
4080 format, type);
4081 break;
4082 case GL_TEXTURE_3D:
4083 /* we'll store 3D images as a series of slices */
4084 numSlices = depth;
4085 sliceOffset = zoffset;
4086 srcImageStride = _mesa_image_image_stride(packing, width, height,
4087 format, type);
4088 break;
4089 case GL_TEXTURE_CUBE_MAP_ARRAY:
4090 numSlices = depth;
4091 sliceOffset = zoffset;
4092 srcImageStride = _mesa_image_image_stride(packing, width, height,
4093 format, type);
4094 break;
4095 default:
4096 _mesa_warning(ctx, "Unexpected target 0x%x in store_texsubimage()", target);
4097 return;
4098 }
4099
4100 assert(numSlices == 1 || srcImageStride != 0);
4101
4102 for (slice = 0; slice < numSlices; slice++) {
4103 GLubyte *dstMap;
4104 GLint dstRowStride;
4105
4106 ctx->Driver.MapTextureImage(ctx, texImage,
4107 slice + sliceOffset,
4108 xoffset, yoffset, width, height,
4109 mapMode, &dstMap, &dstRowStride);
4110 if (dstMap) {
4111 /* Note: we're only storing a 2D (or 1D) slice at a time but we need
4112 * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is
4113 * used for 3D images.
4114 */
4115 success = _mesa_texstore(ctx, dims, texImage->_BaseFormat,
4116 texImage->TexFormat,
4117 dstRowStride,
4118 &dstMap,
4119 width, height, 1, /* w, h, d */
4120 format, type, src, packing);
4121
4122 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset);
4123 }
4124
4125 src += srcImageStride;
4126
4127 if (!success)
4128 break;
4129 }
4130
4131 if (!success)
4132 _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller);
4133
4134 _mesa_unmap_teximage_pbo(ctx, packing);
4135 }
4136
4137
4138
4139 /**
4140 * Fallback code for ctx->Driver.TexImage().
4141 * Basically, allocate storage for the texture image, then copy the
4142 * user's image into it.
4143 */
4144 void
4145 _mesa_store_teximage(struct gl_context *ctx,
4146 GLuint dims,
4147 struct gl_texture_image *texImage,
4148 GLenum format, GLenum type, const GLvoid *pixels,
4149 const struct gl_pixelstore_attrib *packing)
4150 {
4151 assert(dims == 1 || dims == 2 || dims == 3);
4152
4153 if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0)
4154 return;
4155
4156 /* allocate storage for texture data */
4157 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4158 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims);
4159 return;
4160 }
4161
4162 store_texsubimage(ctx, texImage,
4163 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth,
4164 format, type, pixels, packing, "glTexImage");
4165 }
4166
4167
4168 /*
4169 * Fallback for Driver.TexSubImage().
4170 */
4171 void
4172 _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims,
4173 struct gl_texture_image *texImage,
4174 GLint xoffset, GLint yoffset, GLint zoffset,
4175 GLint width, GLint height, GLint depth,
4176 GLenum format, GLenum type, const void *pixels,
4177 const struct gl_pixelstore_attrib *packing)
4178 {
4179 store_texsubimage(ctx, texImage,
4180 xoffset, yoffset, zoffset, width, height, depth,
4181 format, type, pixels, packing, "glTexSubImage");
4182 }
4183
4184
4185 /**
4186 * Fallback for Driver.CompressedTexImage()
4187 */
4188 void
4189 _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims,
4190 struct gl_texture_image *texImage,
4191 GLsizei imageSize, const GLvoid *data)
4192 {
4193 /* only 2D and 3D compressed images are supported at this time */
4194 if (dims == 1) {
4195 _mesa_problem(ctx, "Unexpected glCompressedTexImage1D call");
4196 return;
4197 }
4198
4199 /* This is pretty simple, because unlike the general texstore path we don't
4200 * have to worry about the usual image unpacking or image transfer
4201 * operations.
4202 */
4203 ASSERT(texImage);
4204 ASSERT(texImage->Width > 0);
4205 ASSERT(texImage->Height > 0);
4206 ASSERT(texImage->Depth > 0);
4207
4208 /* allocate storage for texture data */
4209 if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) {
4210 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims);
4211 return;
4212 }
4213
4214 _mesa_store_compressed_texsubimage(ctx, dims, texImage,
4215 0, 0, 0,
4216 texImage->Width, texImage->Height, texImage->Depth,
4217 texImage->TexFormat,
4218 imageSize, data);
4219 }
4220
4221
4222 /**
4223 * Fallback for Driver.CompressedTexSubImage()
4224 */
4225 void
4226 _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims,
4227 struct gl_texture_image *texImage,
4228 GLint xoffset, GLint yoffset, GLint zoffset,
4229 GLsizei width, GLsizei height, GLsizei depth,
4230 GLenum format,
4231 GLsizei imageSize, const GLvoid *data)
4232 {
4233 GLint bytesPerRow, dstRowStride, srcRowStride;
4234 GLint i, rows;
4235 GLubyte *dstMap;
4236 const GLubyte *src;
4237 const mesa_format texFormat = texImage->TexFormat;
4238 GLuint bw, bh;
4239 GLint slice;
4240
4241 if (dims == 1) {
4242 _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call");
4243 return;
4244 }
4245
4246 _mesa_get_format_block_size(texFormat, &bw, &bh);
4247
4248 /* get pointer to src pixels (may be in a pbo which we'll map here) */
4249 data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data,
4250 &ctx->Unpack,
4251 "glCompressedTexSubImage");
4252 if (!data)
4253 return;
4254
4255 srcRowStride = _mesa_format_row_stride(texFormat, width);
4256 src = (const GLubyte *) data;
4257
4258 for (slice = 0; slice < depth; slice++) {
4259 /* Map dest texture buffer */
4260 ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset,
4261 xoffset, yoffset, width, height,
4262 GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT,
4263 &dstMap, &dstRowStride);
4264
4265 if (dstMap) {
4266 bytesPerRow = srcRowStride; /* bytes per row of blocks */
4267 rows = (height + bh - 1) / bh; /* rows in blocks */
4268
4269 /* copy rows of blocks */
4270 for (i = 0; i < rows; i++) {
4271 memcpy(dstMap, src, bytesPerRow);
4272 dstMap += dstRowStride;
4273 src += srcRowStride;
4274 }
4275
4276 ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset);
4277 }
4278 else {
4279 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD",
4280 dims);
4281 }
4282 }
4283
4284 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
4285 }