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