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