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