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