Merge branch 'mesa_7_6_branch'
[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 /*
267 _mesa_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 */
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 *) _mesa_malloc(srcWidth * srcHeight * srcDepth
351 * 4 * sizeof(GLfloat));
352 if (!tempImage)
353 return NULL;
354
355 /* post-convolution image buffer (2D) */
356 convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
357 * 4 * sizeof(GLfloat));
358 if (!convImage) {
359 _mesa_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 _mesa_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 *) _mesa_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 *) _mesa_malloc(srcWidth * srcHeight * srcDepth
476 * texComponents * sizeof(GLfloat));
477 if (!newImage) {
478 _mesa_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 _mesa_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 *) _mesa_malloc(srcWidth * srcHeight * srcDepth
586 * components * sizeof(GLchan));
587 if (!tempImage) {
588 if (freeSrcImage) {
589 _mesa_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 _mesa_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 *) _mesa_malloc(srcWidth * srcHeight * srcDepth
635 * texComponents * sizeof(GLchan));
636 if (!newImage) {
637 _mesa_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 _mesa_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 /* _mesa_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 _mesa_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 _mesa_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 ASSERT(texelBytes == 4);
1415
1416 if (!ctx->_ImageTransferState &&
1417 !srcPacking->SwapBytes &&
1418 (dstFormat == MESA_FORMAT_ARGB8888 ||
1419 dstFormat == MESA_FORMAT_XRGB8888) &&
1420 baseInternalFormat == GL_RGBA &&
1421 srcFormat == GL_BGRA &&
1422 ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1423 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1424 /* simple memcpy path (little endian) */
1425 memcpy_texture(ctx, dims,
1426 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1427 dstRowStride,
1428 dstImageOffsets,
1429 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1430 srcAddr, srcPacking);
1431 }
1432 else if (!ctx->_ImageTransferState &&
1433 !srcPacking->SwapBytes &&
1434 dstFormat == MESA_FORMAT_ARGB8888_REV &&
1435 baseInternalFormat == GL_RGBA &&
1436 srcFormat == GL_BGRA &&
1437 ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1438 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1439 /* simple memcpy path (big endian) */
1440 memcpy_texture(ctx, dims,
1441 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1442 dstRowStride,
1443 dstImageOffsets,
1444 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1445 srcAddr, srcPacking);
1446 }
1447 else if (!ctx->_ImageTransferState &&
1448 !srcPacking->SwapBytes &&
1449 (dstFormat == MESA_FORMAT_ARGB8888 ||
1450 dstFormat == MESA_FORMAT_XRGB8888) &&
1451 srcFormat == GL_RGB &&
1452 (baseInternalFormat == GL_RGBA ||
1453 baseInternalFormat == GL_RGB) &&
1454 srcType == GL_UNSIGNED_BYTE) {
1455 int img, row, col;
1456 for (img = 0; img < srcDepth; img++) {
1457 const GLint srcRowStride =
1458 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1459 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1460 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1461 GLubyte *dstRow = (GLubyte *) dstAddr
1462 + dstImageOffsets[dstZoffset + img] * texelBytes
1463 + dstYoffset * dstRowStride
1464 + dstXoffset * texelBytes;
1465 for (row = 0; row < srcHeight; row++) {
1466 GLuint *d4 = (GLuint *) dstRow;
1467 for (col = 0; col < srcWidth; col++) {
1468 d4[col] = PACK_COLOR_8888(0xff,
1469 srcRow[col * 3 + RCOMP],
1470 srcRow[col * 3 + GCOMP],
1471 srcRow[col * 3 + BCOMP]);
1472 }
1473 dstRow += dstRowStride;
1474 srcRow += srcRowStride;
1475 }
1476 }
1477 }
1478 else if (!ctx->_ImageTransferState &&
1479 !srcPacking->SwapBytes &&
1480 dstFormat == MESA_FORMAT_ARGB8888 &&
1481 srcFormat == GL_RGBA &&
1482 baseInternalFormat == GL_RGBA &&
1483 srcType == GL_UNSIGNED_BYTE) {
1484 /* same as above case, but src data has alpha too */
1485 GLint img, row, col;
1486 /* For some reason, streaming copies to write-combined regions
1487 * are extremely sensitive to the characteristics of how the
1488 * source data is retrieved. By reordering the source reads to
1489 * be in-order, the speed of this operation increases by half.
1490 * Strangely the same isn't required for the RGB path, above.
1491 */
1492 for (img = 0; img < srcDepth; img++) {
1493 const GLint srcRowStride =
1494 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1495 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1496 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1497 GLubyte *dstRow = (GLubyte *) dstAddr
1498 + dstImageOffsets[dstZoffset + img] * texelBytes
1499 + dstYoffset * dstRowStride
1500 + dstXoffset * texelBytes;
1501 for (row = 0; row < srcHeight; row++) {
1502 GLuint *d4 = (GLuint *) dstRow;
1503 for (col = 0; col < srcWidth; col++) {
1504 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1505 srcRow[col * 4 + RCOMP],
1506 srcRow[col * 4 + GCOMP],
1507 srcRow[col * 4 + BCOMP]);
1508 }
1509 dstRow += dstRowStride;
1510 srcRow += srcRowStride;
1511 }
1512 }
1513 }
1514 else if (!ctx->_ImageTransferState &&
1515 (srcType == GL_UNSIGNED_BYTE ||
1516 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1517 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1518 can_swizzle(baseInternalFormat) &&
1519 can_swizzle(srcFormat)) {
1520
1521 GLubyte dstmap[4];
1522
1523 /* dstmap - how to swizzle from RGBA to dst format:
1524 */
1525 if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1526 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1527 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
1528 dstmap[3] = 3; /* alpha */
1529 dstmap[2] = 0; /* red */
1530 dstmap[1] = 1; /* green */
1531 dstmap[0] = 2; /* blue */
1532 }
1533 else {
1534 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1535 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1536 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1537 dstmap[3] = 2;
1538 dstmap[2] = 1;
1539 dstmap[1] = 0;
1540 dstmap[0] = 3;
1541 }
1542
1543 _mesa_swizzle_ubyte_image(ctx, dims,
1544 srcFormat,
1545 srcType,
1546
1547 baseInternalFormat,
1548 dstmap, 4,
1549 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1550 dstRowStride,
1551 dstImageOffsets,
1552 srcWidth, srcHeight, srcDepth, srcAddr,
1553 srcPacking);
1554 }
1555 else {
1556 /* general path */
1557 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1558 baseInternalFormat,
1559 baseFormat,
1560 srcWidth, srcHeight, srcDepth,
1561 srcFormat, srcType, srcAddr,
1562 srcPacking);
1563 const GLchan *src = tempImage;
1564 GLint img, row, col;
1565 if (!tempImage)
1566 return GL_FALSE;
1567 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1568 for (img = 0; img < srcDepth; img++) {
1569 GLubyte *dstRow = (GLubyte *) dstAddr
1570 + dstImageOffsets[dstZoffset + img] * texelBytes
1571 + dstYoffset * dstRowStride
1572 + dstXoffset * texelBytes;
1573 for (row = 0; row < srcHeight; row++) {
1574 GLuint *dstUI = (GLuint *) dstRow;
1575 if (dstFormat == MESA_FORMAT_ARGB8888) {
1576 for (col = 0; col < srcWidth; col++) {
1577 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1578 CHAN_TO_UBYTE(src[RCOMP]),
1579 CHAN_TO_UBYTE(src[GCOMP]),
1580 CHAN_TO_UBYTE(src[BCOMP]) );
1581 src += 4;
1582 }
1583 }
1584 else if (dstFormat == MESA_FORMAT_XRGB8888) {
1585 for (col = 0; col < srcWidth; col++) {
1586 dstUI[col] = PACK_COLOR_8888( 0xff,
1587 CHAN_TO_UBYTE(src[RCOMP]),
1588 CHAN_TO_UBYTE(src[GCOMP]),
1589 CHAN_TO_UBYTE(src[BCOMP]) );
1590 src += 4;
1591 }
1592 }
1593 else {
1594 for (col = 0; col < srcWidth; col++) {
1595 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1596 CHAN_TO_UBYTE(src[RCOMP]),
1597 CHAN_TO_UBYTE(src[GCOMP]),
1598 CHAN_TO_UBYTE(src[BCOMP]) );
1599 src += 4;
1600 }
1601 }
1602 dstRow += dstRowStride;
1603 }
1604 }
1605 _mesa_free((void *) tempImage);
1606 }
1607 return GL_TRUE;
1608 }
1609
1610
1611 static GLboolean
1612 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1613 {
1614 const GLboolean littleEndian = _mesa_little_endian();
1615 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1616 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1617
1618 ASSERT(dstFormat == MESA_FORMAT_RGB888);
1619 ASSERT(texelBytes == 3);
1620
1621 if (!ctx->_ImageTransferState &&
1622 !srcPacking->SwapBytes &&
1623 baseInternalFormat == GL_RGB &&
1624 srcFormat == GL_BGR &&
1625 srcType == GL_UNSIGNED_BYTE &&
1626 littleEndian) {
1627 /* simple memcpy path */
1628 memcpy_texture(ctx, dims,
1629 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1630 dstRowStride,
1631 dstImageOffsets,
1632 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1633 srcAddr, srcPacking);
1634 }
1635 else if (!ctx->_ImageTransferState &&
1636 !srcPacking->SwapBytes &&
1637 srcFormat == GL_RGBA &&
1638 srcType == GL_UNSIGNED_BYTE) {
1639 /* extract RGB from RGBA */
1640 GLint img, row, col;
1641 for (img = 0; img < srcDepth; img++) {
1642 const GLint srcRowStride =
1643 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1644 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1645 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1646 GLubyte *dstRow = (GLubyte *) dstAddr
1647 + dstImageOffsets[dstZoffset + img] * texelBytes
1648 + dstYoffset * dstRowStride
1649 + dstXoffset * texelBytes;
1650 for (row = 0; row < srcHeight; row++) {
1651 for (col = 0; col < srcWidth; col++) {
1652 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1653 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1654 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1655 }
1656 dstRow += dstRowStride;
1657 srcRow += srcRowStride;
1658 }
1659 }
1660 }
1661 else if (!ctx->_ImageTransferState &&
1662 srcType == GL_UNSIGNED_BYTE &&
1663 can_swizzle(baseInternalFormat) &&
1664 can_swizzle(srcFormat)) {
1665
1666 GLubyte dstmap[4];
1667
1668 /* dstmap - how to swizzle from RGBA to dst format:
1669 */
1670 dstmap[0] = 2;
1671 dstmap[1] = 1;
1672 dstmap[2] = 0;
1673 dstmap[3] = ONE; /* ? */
1674
1675 _mesa_swizzle_ubyte_image(ctx, dims,
1676 srcFormat,
1677 srcType,
1678 baseInternalFormat,
1679 dstmap, 3,
1680 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1681 dstRowStride, dstImageOffsets,
1682 srcWidth, srcHeight, srcDepth, srcAddr,
1683 srcPacking);
1684 }
1685 else {
1686 /* general path */
1687 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1688 baseInternalFormat,
1689 baseFormat,
1690 srcWidth, srcHeight, srcDepth,
1691 srcFormat, srcType, srcAddr,
1692 srcPacking);
1693 const GLchan *src = (const GLchan *) tempImage;
1694 GLint img, row, col;
1695 if (!tempImage)
1696 return GL_FALSE;
1697 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1698 for (img = 0; img < srcDepth; img++) {
1699 GLubyte *dstRow = (GLubyte *) dstAddr
1700 + dstImageOffsets[dstZoffset + img] * texelBytes
1701 + dstYoffset * dstRowStride
1702 + dstXoffset * texelBytes;
1703 for (row = 0; row < srcHeight; row++) {
1704 #if 0
1705 if (littleEndian) {
1706 for (col = 0; col < srcWidth; col++) {
1707 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1708 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1709 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1710 srcUB += 3;
1711 }
1712 }
1713 else {
1714 for (col = 0; col < srcWidth; col++) {
1715 dstRow[col * 3 + 0] = srcUB[BCOMP];
1716 dstRow[col * 3 + 1] = srcUB[GCOMP];
1717 dstRow[col * 3 + 2] = srcUB[RCOMP];
1718 srcUB += 3;
1719 }
1720 }
1721 #else
1722 for (col = 0; col < srcWidth; col++) {
1723 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1724 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1725 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1726 src += 3;
1727 }
1728 #endif
1729 dstRow += dstRowStride;
1730 }
1731 }
1732 _mesa_free((void *) tempImage);
1733 }
1734 return GL_TRUE;
1735 }
1736
1737
1738 static GLboolean
1739 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1740 {
1741 const GLboolean littleEndian = _mesa_little_endian();
1742 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1743 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1744
1745 ASSERT(dstFormat == MESA_FORMAT_BGR888);
1746 ASSERT(texelBytes == 3);
1747
1748 if (!ctx->_ImageTransferState &&
1749 !srcPacking->SwapBytes &&
1750 baseInternalFormat == GL_RGB &&
1751 srcFormat == GL_RGB &&
1752 srcType == GL_UNSIGNED_BYTE &&
1753 littleEndian) {
1754 /* simple memcpy path */
1755 memcpy_texture(ctx, dims,
1756 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1757 dstRowStride,
1758 dstImageOffsets,
1759 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1760 srcAddr, srcPacking);
1761 }
1762 else if (!ctx->_ImageTransferState &&
1763 !srcPacking->SwapBytes &&
1764 srcFormat == GL_RGBA &&
1765 srcType == GL_UNSIGNED_BYTE) {
1766 /* extract BGR from RGBA */
1767 int img, row, col;
1768 for (img = 0; img < srcDepth; img++) {
1769 const GLint srcRowStride =
1770 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1771 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1772 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1773 GLubyte *dstRow = (GLubyte *) dstAddr
1774 + dstImageOffsets[dstZoffset + img] * texelBytes
1775 + dstYoffset * dstRowStride
1776 + dstXoffset * texelBytes;
1777 for (row = 0; row < srcHeight; row++) {
1778 for (col = 0; col < srcWidth; col++) {
1779 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1780 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1781 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1782 }
1783 dstRow += dstRowStride;
1784 srcRow += srcRowStride;
1785 }
1786 }
1787 }
1788 else if (!ctx->_ImageTransferState &&
1789 srcType == GL_UNSIGNED_BYTE &&
1790 can_swizzle(baseInternalFormat) &&
1791 can_swizzle(srcFormat)) {
1792
1793 GLubyte dstmap[4];
1794
1795 /* dstmap - how to swizzle from RGBA to dst format:
1796 */
1797 dstmap[0] = 0;
1798 dstmap[1] = 1;
1799 dstmap[2] = 2;
1800 dstmap[3] = ONE; /* ? */
1801
1802 _mesa_swizzle_ubyte_image(ctx, dims,
1803 srcFormat,
1804 srcType,
1805 baseInternalFormat,
1806 dstmap, 3,
1807 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1808 dstRowStride, dstImageOffsets,
1809 srcWidth, srcHeight, srcDepth, srcAddr,
1810 srcPacking);
1811 }
1812 else {
1813 /* general path */
1814 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1815 baseInternalFormat,
1816 baseFormat,
1817 srcWidth, srcHeight, srcDepth,
1818 srcFormat, srcType, srcAddr,
1819 srcPacking);
1820 const GLchan *src = (const GLchan *) tempImage;
1821 GLint img, row, col;
1822 if (!tempImage)
1823 return GL_FALSE;
1824 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1825 for (img = 0; img < srcDepth; img++) {
1826 GLubyte *dstRow = (GLubyte *) dstAddr
1827 + dstImageOffsets[dstZoffset + img] * texelBytes
1828 + dstYoffset * dstRowStride
1829 + dstXoffset * texelBytes;
1830 for (row = 0; row < srcHeight; row++) {
1831 for (col = 0; col < srcWidth; col++) {
1832 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1833 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1834 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1835 src += 3;
1836 }
1837 dstRow += dstRowStride;
1838 }
1839 }
1840 _mesa_free((void *) tempImage);
1841 }
1842 return GL_TRUE;
1843 }
1844
1845
1846 static GLboolean
1847 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1848 {
1849 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1850 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1851
1852 ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1853 dstFormat == MESA_FORMAT_ARGB4444_REV);
1854 ASSERT(texelBytes == 2);
1855
1856 if (!ctx->_ImageTransferState &&
1857 !srcPacking->SwapBytes &&
1858 dstFormat == MESA_FORMAT_ARGB4444 &&
1859 baseInternalFormat == GL_RGBA &&
1860 srcFormat == GL_BGRA &&
1861 srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1862 /* simple memcpy path */
1863 memcpy_texture(ctx, dims,
1864 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1865 dstRowStride,
1866 dstImageOffsets,
1867 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1868 srcAddr, srcPacking);
1869 }
1870 else {
1871 /* general path */
1872 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1873 baseInternalFormat,
1874 baseFormat,
1875 srcWidth, srcHeight, srcDepth,
1876 srcFormat, srcType, srcAddr,
1877 srcPacking);
1878 const GLchan *src = tempImage;
1879 GLint img, row, col;
1880 if (!tempImage)
1881 return GL_FALSE;
1882 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1883 for (img = 0; img < srcDepth; img++) {
1884 GLubyte *dstRow = (GLubyte *) dstAddr
1885 + dstImageOffsets[dstZoffset + img] * texelBytes
1886 + dstYoffset * dstRowStride
1887 + dstXoffset * texelBytes;
1888 for (row = 0; row < srcHeight; row++) {
1889 GLushort *dstUS = (GLushort *) dstRow;
1890 if (dstFormat == MESA_FORMAT_ARGB4444) {
1891 for (col = 0; col < srcWidth; col++) {
1892 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1893 CHAN_TO_UBYTE(src[RCOMP]),
1894 CHAN_TO_UBYTE(src[GCOMP]),
1895 CHAN_TO_UBYTE(src[BCOMP]) );
1896 src += 4;
1897 }
1898 }
1899 else {
1900 for (col = 0; col < srcWidth; col++) {
1901 dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1902 CHAN_TO_UBYTE(src[RCOMP]),
1903 CHAN_TO_UBYTE(src[GCOMP]),
1904 CHAN_TO_UBYTE(src[BCOMP]) );
1905 src += 4;
1906 }
1907 }
1908 dstRow += dstRowStride;
1909 }
1910 }
1911 _mesa_free((void *) tempImage);
1912 }
1913 return GL_TRUE;
1914 }
1915
1916 static GLboolean
1917 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1918 {
1919 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1920 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1921
1922 ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1923 ASSERT(texelBytes == 2);
1924
1925 if (!ctx->_ImageTransferState &&
1926 !srcPacking->SwapBytes &&
1927 dstFormat == MESA_FORMAT_RGBA5551 &&
1928 baseInternalFormat == GL_RGBA &&
1929 srcFormat == GL_RGBA &&
1930 srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
1931 /* simple memcpy path */
1932 memcpy_texture(ctx, dims,
1933 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1934 dstRowStride,
1935 dstImageOffsets,
1936 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1937 srcAddr, srcPacking);
1938 }
1939 else {
1940 /* general path */
1941 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1942 baseInternalFormat,
1943 baseFormat,
1944 srcWidth, srcHeight, srcDepth,
1945 srcFormat, srcType, srcAddr,
1946 srcPacking);
1947 const GLchan *src =tempImage;
1948 GLint img, row, col;
1949 if (!tempImage)
1950 return GL_FALSE;
1951 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1952 for (img = 0; img < srcDepth; img++) {
1953 GLubyte *dstRow = (GLubyte *) dstAddr
1954 + dstImageOffsets[dstZoffset + img] * texelBytes
1955 + dstYoffset * dstRowStride
1956 + dstXoffset * texelBytes;
1957 for (row = 0; row < srcHeight; row++) {
1958 GLushort *dstUS = (GLushort *) dstRow;
1959 for (col = 0; col < srcWidth; col++) {
1960 dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
1961 CHAN_TO_UBYTE(src[GCOMP]),
1962 CHAN_TO_UBYTE(src[BCOMP]),
1963 CHAN_TO_UBYTE(src[ACOMP]) );
1964 src += 4;
1965 }
1966 dstRow += dstRowStride;
1967 }
1968 }
1969 _mesa_free((void *) tempImage);
1970 }
1971 return GL_TRUE;
1972 }
1973
1974 static GLboolean
1975 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
1976 {
1977 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1978 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1979
1980 ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1981 dstFormat == MESA_FORMAT_ARGB1555_REV);
1982 ASSERT(texelBytes == 2);
1983
1984 if (!ctx->_ImageTransferState &&
1985 !srcPacking->SwapBytes &&
1986 dstFormat == MESA_FORMAT_ARGB1555 &&
1987 baseInternalFormat == GL_RGBA &&
1988 srcFormat == GL_BGRA &&
1989 srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1990 /* simple memcpy path */
1991 memcpy_texture(ctx, dims,
1992 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1993 dstRowStride,
1994 dstImageOffsets,
1995 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1996 srcAddr, srcPacking);
1997 }
1998 else {
1999 /* general path */
2000 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2001 baseInternalFormat,
2002 baseFormat,
2003 srcWidth, srcHeight, srcDepth,
2004 srcFormat, srcType, srcAddr,
2005 srcPacking);
2006 const GLchan *src =tempImage;
2007 GLint img, row, col;
2008 if (!tempImage)
2009 return GL_FALSE;
2010 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2011 for (img = 0; img < srcDepth; img++) {
2012 GLubyte *dstRow = (GLubyte *) dstAddr
2013 + dstImageOffsets[dstZoffset + img] * texelBytes
2014 + dstYoffset * dstRowStride
2015 + dstXoffset * texelBytes;
2016 for (row = 0; row < srcHeight; row++) {
2017 GLushort *dstUS = (GLushort *) dstRow;
2018 if (dstFormat == MESA_FORMAT_ARGB1555) {
2019 for (col = 0; col < srcWidth; col++) {
2020 dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
2021 CHAN_TO_UBYTE(src[RCOMP]),
2022 CHAN_TO_UBYTE(src[GCOMP]),
2023 CHAN_TO_UBYTE(src[BCOMP]) );
2024 src += 4;
2025 }
2026 }
2027 else {
2028 for (col = 0; col < srcWidth; col++) {
2029 dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
2030 CHAN_TO_UBYTE(src[RCOMP]),
2031 CHAN_TO_UBYTE(src[GCOMP]),
2032 CHAN_TO_UBYTE(src[BCOMP]) );
2033 src += 4;
2034 }
2035 }
2036 dstRow += dstRowStride;
2037 }
2038 }
2039 _mesa_free((void *) tempImage);
2040 }
2041 return GL_TRUE;
2042 }
2043
2044
2045 static GLboolean
2046 _mesa_texstore_al88(TEXSTORE_PARAMS)
2047 {
2048 const GLboolean littleEndian = _mesa_little_endian();
2049 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2050 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2051
2052 ASSERT(dstFormat == MESA_FORMAT_AL88 ||
2053 dstFormat == MESA_FORMAT_AL88_REV);
2054 ASSERT(texelBytes == 2);
2055
2056 if (!ctx->_ImageTransferState &&
2057 !srcPacking->SwapBytes &&
2058 dstFormat == MESA_FORMAT_AL88 &&
2059 baseInternalFormat == GL_LUMINANCE_ALPHA &&
2060 srcFormat == GL_LUMINANCE_ALPHA &&
2061 srcType == GL_UNSIGNED_BYTE &&
2062 littleEndian) {
2063 /* simple memcpy path */
2064 memcpy_texture(ctx, dims,
2065 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2066 dstRowStride,
2067 dstImageOffsets,
2068 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2069 srcAddr, srcPacking);
2070 }
2071 else if (!ctx->_ImageTransferState &&
2072 littleEndian &&
2073 srcType == GL_UNSIGNED_BYTE &&
2074 can_swizzle(baseInternalFormat) &&
2075 can_swizzle(srcFormat)) {
2076
2077 GLubyte dstmap[4];
2078
2079 /* dstmap - how to swizzle from RGBA to dst format:
2080 */
2081 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
2082 (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
2083 dstmap[0] = 0;
2084 dstmap[1] = 3;
2085 }
2086 else {
2087 dstmap[0] = 3;
2088 dstmap[1] = 0;
2089 }
2090 dstmap[2] = ZERO; /* ? */
2091 dstmap[3] = ONE; /* ? */
2092
2093 _mesa_swizzle_ubyte_image(ctx, dims,
2094 srcFormat,
2095 srcType,
2096 baseInternalFormat,
2097 dstmap, 2,
2098 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2099 dstRowStride, dstImageOffsets,
2100 srcWidth, srcHeight, srcDepth, srcAddr,
2101 srcPacking);
2102 }
2103 else {
2104 /* general path */
2105 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2106 baseInternalFormat,
2107 baseFormat,
2108 srcWidth, srcHeight, srcDepth,
2109 srcFormat, srcType, srcAddr,
2110 srcPacking);
2111 const GLchan *src = tempImage;
2112 GLint img, row, col;
2113 if (!tempImage)
2114 return GL_FALSE;
2115 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2116 for (img = 0; img < srcDepth; img++) {
2117 GLubyte *dstRow = (GLubyte *) dstAddr
2118 + dstImageOffsets[dstZoffset + img] * texelBytes
2119 + dstYoffset * dstRowStride
2120 + dstXoffset * texelBytes;
2121 for (row = 0; row < srcHeight; row++) {
2122 GLushort *dstUS = (GLushort *) dstRow;
2123 if (dstFormat == MESA_FORMAT_AL88) {
2124 for (col = 0; col < srcWidth; col++) {
2125 /* src[0] is luminance, src[1] is alpha */
2126 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
2127 CHAN_TO_UBYTE(src[0]) );
2128 src += 2;
2129 }
2130 }
2131 else {
2132 for (col = 0; col < srcWidth; col++) {
2133 /* src[0] is luminance, src[1] is alpha */
2134 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
2135 CHAN_TO_UBYTE(src[0]) );
2136 src += 2;
2137 }
2138 }
2139 dstRow += dstRowStride;
2140 }
2141 }
2142 _mesa_free((void *) tempImage);
2143 }
2144 return GL_TRUE;
2145 }
2146
2147
2148 static GLboolean
2149 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2150 {
2151 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2152 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2153
2154 ASSERT(dstFormat == MESA_FORMAT_RGB332);
2155 ASSERT(texelBytes == 1);
2156
2157 if (!ctx->_ImageTransferState &&
2158 !srcPacking->SwapBytes &&
2159 baseInternalFormat == GL_RGB &&
2160 srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2161 /* simple memcpy path */
2162 memcpy_texture(ctx, dims,
2163 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2164 dstRowStride,
2165 dstImageOffsets,
2166 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2167 srcAddr, srcPacking);
2168 }
2169 else {
2170 /* general path */
2171 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2172 baseInternalFormat,
2173 baseFormat,
2174 srcWidth, srcHeight, srcDepth,
2175 srcFormat, srcType, srcAddr,
2176 srcPacking);
2177 const GLchan *src = tempImage;
2178 GLint img, row, col;
2179 if (!tempImage)
2180 return GL_FALSE;
2181 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2182 for (img = 0; img < srcDepth; img++) {
2183 GLubyte *dstRow = (GLubyte *) dstAddr
2184 + dstImageOffsets[dstZoffset + img] * texelBytes
2185 + dstYoffset * dstRowStride
2186 + dstXoffset * texelBytes;
2187 for (row = 0; row < srcHeight; row++) {
2188 for (col = 0; col < srcWidth; col++) {
2189 dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
2190 CHAN_TO_UBYTE(src[GCOMP]),
2191 CHAN_TO_UBYTE(src[BCOMP]) );
2192 src += 3;
2193 }
2194 dstRow += dstRowStride;
2195 }
2196 }
2197 _mesa_free((void *) tempImage);
2198 }
2199 return GL_TRUE;
2200 }
2201
2202
2203 /**
2204 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2205 */
2206 static GLboolean
2207 _mesa_texstore_a8(TEXSTORE_PARAMS)
2208 {
2209 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2210 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2211
2212 ASSERT(dstFormat == MESA_FORMAT_A8 ||
2213 dstFormat == MESA_FORMAT_L8 ||
2214 dstFormat == MESA_FORMAT_I8);
2215 ASSERT(texelBytes == 1);
2216
2217 if (!ctx->_ImageTransferState &&
2218 !srcPacking->SwapBytes &&
2219 baseInternalFormat == srcFormat &&
2220 srcType == GL_UNSIGNED_BYTE) {
2221 /* simple memcpy path */
2222 memcpy_texture(ctx, dims,
2223 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2224 dstRowStride,
2225 dstImageOffsets,
2226 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2227 srcAddr, srcPacking);
2228 }
2229 else if (!ctx->_ImageTransferState &&
2230 srcType == GL_UNSIGNED_BYTE &&
2231 can_swizzle(baseInternalFormat) &&
2232 can_swizzle(srcFormat)) {
2233
2234 GLubyte dstmap[4];
2235
2236 /* dstmap - how to swizzle from RGBA to dst format:
2237 */
2238 if (dstFormat == MESA_FORMAT_A8) {
2239 dstmap[0] = 3;
2240 }
2241 else {
2242 dstmap[0] = 0;
2243 }
2244 dstmap[1] = ZERO; /* ? */
2245 dstmap[2] = ZERO; /* ? */
2246 dstmap[3] = ONE; /* ? */
2247
2248 _mesa_swizzle_ubyte_image(ctx, dims,
2249 srcFormat,
2250 srcType,
2251 baseInternalFormat,
2252 dstmap, 1,
2253 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2254 dstRowStride, dstImageOffsets,
2255 srcWidth, srcHeight, srcDepth, srcAddr,
2256 srcPacking);
2257 }
2258 else {
2259 /* general path */
2260 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2261 baseInternalFormat,
2262 baseFormat,
2263 srcWidth, srcHeight, srcDepth,
2264 srcFormat, srcType, srcAddr,
2265 srcPacking);
2266 const GLchan *src = tempImage;
2267 GLint img, row, col;
2268 if (!tempImage)
2269 return GL_FALSE;
2270 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2271 for (img = 0; img < srcDepth; img++) {
2272 GLubyte *dstRow = (GLubyte *) dstAddr
2273 + dstImageOffsets[dstZoffset + img] * texelBytes
2274 + dstYoffset * dstRowStride
2275 + dstXoffset * texelBytes;
2276 for (row = 0; row < srcHeight; row++) {
2277 for (col = 0; col < srcWidth; col++) {
2278 dstRow[col] = CHAN_TO_UBYTE(src[col]);
2279 }
2280 dstRow += dstRowStride;
2281 src += srcWidth;
2282 }
2283 }
2284 _mesa_free((void *) tempImage);
2285 }
2286 return GL_TRUE;
2287 }
2288
2289
2290
2291 static GLboolean
2292 _mesa_texstore_ci8(TEXSTORE_PARAMS)
2293 {
2294 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2295
2296 (void) dims; (void) baseInternalFormat;
2297 ASSERT(dstFormat == MESA_FORMAT_CI8);
2298 ASSERT(texelBytes == 1);
2299 ASSERT(baseInternalFormat == GL_COLOR_INDEX);
2300
2301 if (!ctx->_ImageTransferState &&
2302 !srcPacking->SwapBytes &&
2303 srcFormat == GL_COLOR_INDEX &&
2304 srcType == GL_UNSIGNED_BYTE) {
2305 /* simple memcpy path */
2306 memcpy_texture(ctx, dims,
2307 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2308 dstRowStride,
2309 dstImageOffsets,
2310 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2311 srcAddr, srcPacking);
2312 }
2313 else {
2314 /* general path */
2315 GLint img, row;
2316 for (img = 0; img < srcDepth; img++) {
2317 GLubyte *dstRow = (GLubyte *) dstAddr
2318 + dstImageOffsets[dstZoffset + img] * texelBytes
2319 + dstYoffset * dstRowStride
2320 + dstXoffset * texelBytes;
2321 for (row = 0; row < srcHeight; row++) {
2322 const GLvoid *src = _mesa_image_address(dims, srcPacking,
2323 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2324 _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
2325 srcType, src, srcPacking,
2326 ctx->_ImageTransferState);
2327 dstRow += dstRowStride;
2328 }
2329 }
2330 }
2331 return GL_TRUE;
2332 }
2333
2334
2335 /**
2336 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2337 */
2338 static GLboolean
2339 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2340 {
2341 const GLboolean littleEndian = _mesa_little_endian();
2342 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2343
2344 (void) ctx; (void) dims; (void) baseInternalFormat;
2345
2346 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2347 (dstFormat == MESA_FORMAT_YCBCR_REV));
2348 ASSERT(texelBytes == 2);
2349 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2350 ASSERT(srcFormat == GL_YCBCR_MESA);
2351 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2352 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2353 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2354
2355 /* always just memcpy since no pixel transfer ops apply */
2356 memcpy_texture(ctx, dims,
2357 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2358 dstRowStride,
2359 dstImageOffsets,
2360 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2361 srcAddr, srcPacking);
2362
2363 /* Check if we need byte swapping */
2364 /* XXX the logic here _might_ be wrong */
2365 if (srcPacking->SwapBytes ^
2366 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2367 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2368 !littleEndian) {
2369 GLint img, row;
2370 for (img = 0; img < srcDepth; img++) {
2371 GLubyte *dstRow = (GLubyte *) dstAddr
2372 + dstImageOffsets[dstZoffset + img] * texelBytes
2373 + dstYoffset * dstRowStride
2374 + dstXoffset * texelBytes;
2375 for (row = 0; row < srcHeight; row++) {
2376 _mesa_swap2((GLushort *) dstRow, srcWidth);
2377 dstRow += dstRowStride;
2378 }
2379 }
2380 }
2381 return GL_TRUE;
2382 }
2383
2384 static GLboolean
2385 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2386 {
2387 const GLboolean littleEndian = _mesa_little_endian();
2388 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2389
2390 ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2391 ASSERT(texelBytes == 2);
2392 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2393 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2394 (srcFormat == GL_DUDV_ATI));
2395 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2396
2397 if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2398 littleEndian) {
2399 /* simple memcpy path */
2400 memcpy_texture(ctx, dims,
2401 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2402 dstRowStride,
2403 dstImageOffsets,
2404 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2405 srcAddr, srcPacking);
2406 }
2407 else if (srcType == GL_BYTE) {
2408
2409 GLubyte dstmap[4];
2410
2411 /* dstmap - how to swizzle from RGBA to dst format:
2412 */
2413 if (littleEndian) {
2414 dstmap[0] = 0;
2415 dstmap[1] = 3;
2416 }
2417 else {
2418 dstmap[0] = 3;
2419 dstmap[1] = 0;
2420 }
2421 dstmap[2] = ZERO; /* ? */
2422 dstmap[3] = ONE; /* ? */
2423
2424 _mesa_swizzle_ubyte_image(ctx, dims,
2425 GL_LUMINANCE_ALPHA, /* hack */
2426 GL_UNSIGNED_BYTE, /* hack */
2427 GL_LUMINANCE_ALPHA, /* hack */
2428 dstmap, 2,
2429 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2430 dstRowStride, dstImageOffsets,
2431 srcWidth, srcHeight, srcDepth, srcAddr,
2432 srcPacking);
2433 }
2434 else {
2435 /* general path - note this is defined for 2d textures only */
2436 const GLint components = _mesa_components_in_format(baseInternalFormat);
2437 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2438 srcFormat, srcType);
2439 GLbyte *tempImage, *dst, *src;
2440 GLint row;
2441
2442 tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
2443 * components * sizeof(GLbyte));
2444 if (!tempImage)
2445 return GL_FALSE;
2446
2447 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2448 srcWidth, srcHeight,
2449 srcFormat, srcType,
2450 0, 0, 0);
2451
2452 dst = tempImage;
2453 for (row = 0; row < srcHeight; row++) {
2454 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2455 dst, srcFormat, srcType, src,
2456 srcPacking, 0);
2457 dst += srcWidth * components;
2458 src += srcStride;
2459 }
2460
2461 src = tempImage;
2462 dst = (GLbyte *) dstAddr
2463 + dstYoffset * dstRowStride
2464 + dstXoffset * texelBytes;
2465 for (row = 0; row < srcHeight; row++) {
2466 memcpy(dst, src, srcWidth * texelBytes);
2467 dst += dstRowStride;
2468 src += srcWidth * texelBytes;
2469 }
2470 _mesa_free((void *) tempImage);
2471 }
2472 return GL_TRUE;
2473 }
2474
2475 /**
2476 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2477 */
2478 static GLboolean
2479 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2480 {
2481 const GLboolean littleEndian = _mesa_little_endian();
2482 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2483 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2484
2485 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
2486 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
2487 ASSERT(texelBytes == 4);
2488
2489 if (!ctx->_ImageTransferState &&
2490 !srcPacking->SwapBytes &&
2491 dstFormat == MESA_FORMAT_SIGNED_RGBA8888 &&
2492 baseInternalFormat == GL_RGBA &&
2493 ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
2494 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
2495 /* simple memcpy path */
2496 memcpy_texture(ctx, dims,
2497 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2498 dstRowStride,
2499 dstImageOffsets,
2500 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2501 srcAddr, srcPacking);
2502 }
2503 else if (!ctx->_ImageTransferState &&
2504 !srcPacking->SwapBytes &&
2505 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV &&
2506 baseInternalFormat == GL_RGBA &&
2507 ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
2508 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
2509 /* simple memcpy path */
2510 memcpy_texture(ctx, dims,
2511 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2512 dstRowStride,
2513 dstImageOffsets,
2514 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2515 srcAddr, srcPacking);
2516 }
2517 else if (!ctx->_ImageTransferState &&
2518 (srcType == GL_BYTE) &&
2519 can_swizzle(baseInternalFormat) &&
2520 can_swizzle(srcFormat)) {
2521
2522 GLubyte dstmap[4];
2523
2524 /* dstmap - how to swizzle from RGBA to dst format:
2525 */
2526 if ((littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888) ||
2527 (!littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV)) {
2528 dstmap[3] = 0;
2529 dstmap[2] = 1;
2530 dstmap[1] = 2;
2531 dstmap[0] = 3;
2532 }
2533 else {
2534 dstmap[3] = 3;
2535 dstmap[2] = 2;
2536 dstmap[1] = 1;
2537 dstmap[0] = 0;
2538 }
2539
2540 _mesa_swizzle_ubyte_image(ctx, dims,
2541 srcFormat,
2542 srcType,
2543 baseInternalFormat,
2544 dstmap, 4,
2545 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2546 dstRowStride, dstImageOffsets,
2547 srcWidth, srcHeight, srcDepth, srcAddr,
2548 srcPacking);
2549 }
2550 else {
2551 /* general path */
2552 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2553 baseInternalFormat,
2554 baseFormat,
2555 srcWidth, srcHeight, srcDepth,
2556 srcFormat, srcType, srcAddr,
2557 srcPacking);
2558 const GLfloat *srcRow = tempImage;
2559 GLint img, row, col;
2560 if (!tempImage)
2561 return GL_FALSE;
2562 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2563 for (img = 0; img < srcDepth; img++) {
2564 GLubyte *dstRow = (GLubyte *) dstAddr
2565 + dstImageOffsets[dstZoffset + img] * texelBytes
2566 + dstYoffset * dstRowStride
2567 + dstXoffset * texelBytes;
2568 for (row = 0; row < srcHeight; row++) {
2569 GLuint *dstUI = (GLuint *) dstRow;
2570 if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
2571 for (col = 0; col < srcWidth; col++) {
2572 dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2573 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2574 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2575 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2576 srcRow += 4;
2577 }
2578 }
2579 else {
2580 for (col = 0; col < srcWidth; col++) {
2581 dstUI[col] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2582 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2583 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2584 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2585 srcRow += 4;
2586 }
2587 }
2588 dstRow += dstRowStride;
2589 }
2590 }
2591 _mesa_free((void *) tempImage);
2592 }
2593 return GL_TRUE;
2594 }
2595
2596 /**
2597 * Store a combined depth/stencil texture image.
2598 */
2599 static GLboolean
2600 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2601 {
2602 const GLfloat depthScale = (GLfloat) 0xffffff;
2603 const GLint srcRowStride
2604 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2605 / sizeof(GLuint);
2606 GLint img, row;
2607
2608 ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
2609 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2610 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2611
2612 /* In case we only upload depth we need to preserve the stencil */
2613 if (srcFormat == GL_DEPTH_COMPONENT) {
2614 for (img = 0; img < srcDepth; img++) {
2615 GLuint *dstRow = (GLuint *) dstAddr
2616 + dstImageOffsets[dstZoffset + img]
2617 + dstYoffset * dstRowStride / sizeof(GLuint)
2618 + dstXoffset;
2619 const GLuint *src
2620 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2621 srcWidth, srcHeight,
2622 srcFormat, srcType,
2623 img, 0, 0);
2624 for (row = 0; row < srcHeight; row++) {
2625 GLuint depth[MAX_WIDTH];
2626 GLint i;
2627 _mesa_unpack_depth_span(ctx, srcWidth,
2628 GL_UNSIGNED_INT, /* dst type */
2629 depth, /* dst addr */
2630 depthScale,
2631 srcType, src, srcPacking);
2632
2633 for (i = 0; i < srcWidth; i++)
2634 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2635
2636 src += srcRowStride;
2637 dstRow += dstRowStride / sizeof(GLuint);
2638 }
2639 }
2640 }
2641 else if (ctx->Pixel.DepthScale == 1.0f &&
2642 ctx->Pixel.DepthBias == 0.0f &&
2643 !srcPacking->SwapBytes) {
2644 /* simple path */
2645 memcpy_texture(ctx, dims,
2646 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2647 dstRowStride,
2648 dstImageOffsets,
2649 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2650 srcAddr, srcPacking);
2651 }
2652 else {
2653 /* general path */
2654 const GLint srcRowStride
2655 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2656 / sizeof(GLuint);
2657 GLint img, row;
2658
2659 for (img = 0; img < srcDepth; img++) {
2660 GLuint *dstRow = (GLuint *) dstAddr
2661 + dstImageOffsets[dstZoffset + img]
2662 + dstYoffset * dstRowStride / sizeof(GLuint)
2663 + dstXoffset;
2664 const GLuint *src
2665 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2666 srcWidth, srcHeight,
2667 srcFormat, srcType,
2668 img, 0, 0);
2669 for (row = 0; row < srcHeight; row++) {
2670 GLubyte stencil[MAX_WIDTH];
2671 GLint i;
2672 /* the 24 depth bits will be in the high position: */
2673 _mesa_unpack_depth_span(ctx, srcWidth,
2674 GL_UNSIGNED_INT_24_8_EXT, /* dst type */
2675 dstRow, /* dst addr */
2676 (GLuint) depthScale,
2677 srcType, src, srcPacking);
2678 /* get the 8-bit stencil values */
2679 _mesa_unpack_stencil_span(ctx, srcWidth,
2680 GL_UNSIGNED_BYTE, /* dst type */
2681 stencil, /* dst addr */
2682 srcType, src, srcPacking,
2683 ctx->_ImageTransferState);
2684 /* merge stencil values into depth values */
2685 for (i = 0; i < srcWidth; i++)
2686 dstRow[i] |= stencil[i];
2687
2688 src += srcRowStride;
2689 dstRow += dstRowStride / sizeof(GLuint);
2690 }
2691 }
2692 }
2693 return GL_TRUE;
2694 }
2695
2696
2697 /**
2698 * Store a combined depth/stencil texture image.
2699 */
2700 static GLboolean
2701 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2702 {
2703 const GLuint depthScale = 0xffffff;
2704 const GLint srcRowStride
2705 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2706 / sizeof(GLuint);
2707 GLint img, row;
2708
2709 ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
2710 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2711 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2712
2713 /* In case we only upload depth we need to preserve the stencil */
2714 if (srcFormat == GL_DEPTH_COMPONENT) {
2715 for (img = 0; img < srcDepth; img++) {
2716 GLuint *dstRow = (GLuint *) dstAddr
2717 + dstImageOffsets[dstZoffset + img]
2718 + dstYoffset * dstRowStride / sizeof(GLuint)
2719 + dstXoffset;
2720 const GLuint *src
2721 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2722 srcWidth, srcHeight,
2723 srcFormat, srcType,
2724 img, 0, 0);
2725 for (row = 0; row < srcHeight; row++) {
2726 GLuint depth[MAX_WIDTH];
2727 GLint i;
2728 _mesa_unpack_depth_span(ctx, srcWidth,
2729 GL_UNSIGNED_INT, /* dst type */
2730 depth, /* dst addr */
2731 depthScale,
2732 srcType, src, srcPacking);
2733
2734 for (i = 0; i < srcWidth; i++)
2735 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2736
2737 src += srcRowStride;
2738 dstRow += dstRowStride / sizeof(GLuint);
2739 }
2740 }
2741 }
2742 else {
2743 for (img = 0; img < srcDepth; img++) {
2744 GLuint *dstRow = (GLuint *) dstAddr
2745 + dstImageOffsets[dstZoffset + img]
2746 + dstYoffset * dstRowStride / sizeof(GLuint)
2747 + dstXoffset;
2748 const GLuint *src
2749 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2750 srcWidth, srcHeight,
2751 srcFormat, srcType,
2752 img, 0, 0);
2753 for (row = 0; row < srcHeight; row++) {
2754 GLubyte stencil[MAX_WIDTH];
2755 GLint i;
2756 /* the 24 depth bits will be in the low position: */
2757 _mesa_unpack_depth_span(ctx, srcWidth,
2758 GL_UNSIGNED_INT, /* dst type */
2759 dstRow, /* dst addr */
2760 depthScale,
2761 srcType, src, srcPacking);
2762 /* get the 8-bit stencil values */
2763 _mesa_unpack_stencil_span(ctx, srcWidth,
2764 GL_UNSIGNED_BYTE, /* dst type */
2765 stencil, /* dst addr */
2766 srcType, src, srcPacking,
2767 ctx->_ImageTransferState);
2768 /* merge stencil values into depth values */
2769 for (i = 0; i < srcWidth; i++)
2770 dstRow[i] |= stencil[i] << 24;
2771
2772 src += srcRowStride;
2773 dstRow += dstRowStride / sizeof(GLuint);
2774 }
2775 }
2776 }
2777 return GL_TRUE;
2778 }
2779
2780 /**
2781 * Store an image in any of the formats:
2782 * _mesa_texformat_rgba_float32
2783 * _mesa_texformat_rgb_float32
2784 * _mesa_texformat_alpha_float32
2785 * _mesa_texformat_luminance_float32
2786 * _mesa_texformat_luminance_alpha_float32
2787 * _mesa_texformat_intensity_float32
2788 */
2789 static GLboolean
2790 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2791 {
2792 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2793 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2794 const GLint components = _mesa_components_in_format(baseFormat);
2795
2796 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
2797 dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
2798 dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
2799 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
2800 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
2801 dstFormat == MESA_FORMAT_INTENSITY_FLOAT32);
2802 ASSERT(baseInternalFormat == GL_RGBA ||
2803 baseInternalFormat == GL_RGB ||
2804 baseInternalFormat == GL_ALPHA ||
2805 baseInternalFormat == GL_LUMINANCE ||
2806 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2807 baseInternalFormat == GL_INTENSITY);
2808 ASSERT(texelBytes == components * sizeof(GLfloat));
2809
2810 if (!ctx->_ImageTransferState &&
2811 !srcPacking->SwapBytes &&
2812 baseInternalFormat == srcFormat &&
2813 srcType == GL_FLOAT) {
2814 /* simple memcpy path */
2815 memcpy_texture(ctx, dims,
2816 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2817 dstRowStride,
2818 dstImageOffsets,
2819 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2820 srcAddr, srcPacking);
2821 }
2822 else {
2823 /* general path */
2824 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2825 baseInternalFormat,
2826 baseFormat,
2827 srcWidth, srcHeight, srcDepth,
2828 srcFormat, srcType, srcAddr,
2829 srcPacking);
2830 const GLfloat *srcRow = tempImage;
2831 GLint bytesPerRow;
2832 GLint img, row;
2833 if (!tempImage)
2834 return GL_FALSE;
2835 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2836 bytesPerRow = srcWidth * components * sizeof(GLfloat);
2837 for (img = 0; img < srcDepth; img++) {
2838 GLubyte *dstRow = (GLubyte *) dstAddr
2839 + dstImageOffsets[dstZoffset + img] * texelBytes
2840 + dstYoffset * dstRowStride
2841 + dstXoffset * texelBytes;
2842 for (row = 0; row < srcHeight; row++) {
2843 _mesa_memcpy(dstRow, srcRow, bytesPerRow);
2844 dstRow += dstRowStride;
2845 srcRow += srcWidth * components;
2846 }
2847 }
2848
2849 _mesa_free((void *) tempImage);
2850 }
2851 return GL_TRUE;
2852 }
2853
2854
2855 /**
2856 * As above, but store 16-bit floats.
2857 */
2858 static GLboolean
2859 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2860 {
2861 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2862 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2863 const GLint components = _mesa_components_in_format(baseFormat);
2864
2865 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
2866 dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
2867 dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
2868 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
2869 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
2870 dstFormat == MESA_FORMAT_INTENSITY_FLOAT16);
2871 ASSERT(baseInternalFormat == GL_RGBA ||
2872 baseInternalFormat == GL_RGB ||
2873 baseInternalFormat == GL_ALPHA ||
2874 baseInternalFormat == GL_LUMINANCE ||
2875 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2876 baseInternalFormat == GL_INTENSITY);
2877 ASSERT(texelBytes == components * sizeof(GLhalfARB));
2878
2879 if (!ctx->_ImageTransferState &&
2880 !srcPacking->SwapBytes &&
2881 baseInternalFormat == srcFormat &&
2882 srcType == GL_HALF_FLOAT_ARB) {
2883 /* simple memcpy path */
2884 memcpy_texture(ctx, dims,
2885 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2886 dstRowStride,
2887 dstImageOffsets,
2888 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2889 srcAddr, srcPacking);
2890 }
2891 else {
2892 /* general path */
2893 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2894 baseInternalFormat,
2895 baseFormat,
2896 srcWidth, srcHeight, srcDepth,
2897 srcFormat, srcType, srcAddr,
2898 srcPacking);
2899 const GLfloat *src = tempImage;
2900 GLint img, row;
2901 if (!tempImage)
2902 return GL_FALSE;
2903 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2904 for (img = 0; img < srcDepth; img++) {
2905 GLubyte *dstRow = (GLubyte *) dstAddr
2906 + dstImageOffsets[dstZoffset + img] * texelBytes
2907 + dstYoffset * dstRowStride
2908 + dstXoffset * texelBytes;
2909 for (row = 0; row < srcHeight; row++) {
2910 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2911 GLint i;
2912 for (i = 0; i < srcWidth * components; i++) {
2913 dstTexel[i] = _mesa_float_to_half(src[i]);
2914 }
2915 dstRow += dstRowStride;
2916 src += srcWidth * components;
2917 }
2918 }
2919
2920 _mesa_free((void *) tempImage);
2921 }
2922 return GL_TRUE;
2923 }
2924
2925
2926 #if FEATURE_EXT_texture_sRGB
2927 static GLboolean
2928 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
2929 {
2930 gl_format newDstFormat;
2931 GLboolean k;
2932
2933 ASSERT(dstFormat == MESA_FORMAT_SRGB8);
2934
2935 /* reuse normal rgb texstore code */
2936 newDstFormat = MESA_FORMAT_RGB888;
2937
2938 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
2939 newDstFormat, dstAddr,
2940 dstXoffset, dstYoffset, dstZoffset,
2941 dstRowStride, dstImageOffsets,
2942 srcWidth, srcHeight, srcDepth,
2943 srcFormat, srcType,
2944 srcAddr, srcPacking);
2945 return k;
2946 }
2947
2948
2949 static GLboolean
2950 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
2951 {
2952 gl_format newDstFormat;
2953 GLboolean k;
2954
2955 ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
2956
2957 /* reuse normal rgba texstore code */
2958 newDstFormat = MESA_FORMAT_RGBA8888;
2959 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
2960 newDstFormat, dstAddr,
2961 dstXoffset, dstYoffset, dstZoffset,
2962 dstRowStride, dstImageOffsets,
2963 srcWidth, srcHeight, srcDepth,
2964 srcFormat, srcType,
2965 srcAddr, srcPacking);
2966 return k;
2967 }
2968
2969
2970 static GLboolean
2971 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
2972 {
2973 gl_format newDstFormat;
2974 GLboolean k;
2975
2976 ASSERT(dstFormat == MESA_FORMAT_SARGB8);
2977
2978 /* reuse normal rgba texstore code */
2979 newDstFormat = MESA_FORMAT_ARGB8888;
2980
2981 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
2982 newDstFormat, dstAddr,
2983 dstXoffset, dstYoffset, dstZoffset,
2984 dstRowStride, dstImageOffsets,
2985 srcWidth, srcHeight, srcDepth,
2986 srcFormat, srcType,
2987 srcAddr, srcPacking);
2988 return k;
2989 }
2990
2991
2992 static GLboolean
2993 _mesa_texstore_sl8(TEXSTORE_PARAMS)
2994 {
2995 gl_format newDstFormat;
2996 GLboolean k;
2997
2998 ASSERT(dstFormat == MESA_FORMAT_SL8);
2999
3000 newDstFormat = MESA_FORMAT_L8;
3001
3002 /* _mesa_textore_a8 handles luminance8 too */
3003 k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
3004 newDstFormat, dstAddr,
3005 dstXoffset, dstYoffset, dstZoffset,
3006 dstRowStride, dstImageOffsets,
3007 srcWidth, srcHeight, srcDepth,
3008 srcFormat, srcType,
3009 srcAddr, srcPacking);
3010 return k;
3011 }
3012
3013
3014 static GLboolean
3015 _mesa_texstore_sla8(TEXSTORE_PARAMS)
3016 {
3017 gl_format newDstFormat;
3018 GLboolean k;
3019
3020 ASSERT(dstFormat == MESA_FORMAT_SLA8);
3021
3022 /* reuse normal luminance/alpha texstore code */
3023 newDstFormat = MESA_FORMAT_AL88;
3024
3025 k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
3026 newDstFormat, dstAddr,
3027 dstXoffset, dstYoffset, dstZoffset,
3028 dstRowStride, dstImageOffsets,
3029 srcWidth, srcHeight, srcDepth,
3030 srcFormat, srcType,
3031 srcAddr, srcPacking);
3032 return k;
3033 }
3034
3035 #else
3036
3037 /* these are used only in texstore_funcs[] below */
3038 #define _mesa_texstore_srgb8 NULL
3039 #define _mesa_texstore_srgba8 NULL
3040 #define _mesa_texstore_sargb8 NULL
3041 #define _mesa_texstore_sl8 NULL
3042 #define _mesa_texstore_sla8 NULL
3043
3044 #endif /* FEATURE_EXT_texture_sRGB */
3045
3046
3047
3048
3049 /**
3050 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
3051 * XXX this is somewhat temporary.
3052 */
3053 const static struct {
3054 gl_format Name;
3055 StoreTexImageFunc Store;
3056 }
3057 texstore_funcs[MESA_FORMAT_COUNT] =
3058 {
3059 { MESA_FORMAT_NONE, NULL },
3060 { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 },
3061 { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
3062 { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
3063 { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
3064 { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
3065 { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
3066 { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
3067 { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
3068 { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
3069 { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
3070 { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
3071 { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
3072 { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
3073 { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
3074 { MESA_FORMAT_AL88, _mesa_texstore_al88 },
3075 { MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
3076 { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
3077 { MESA_FORMAT_A8, _mesa_texstore_a8 },
3078 { MESA_FORMAT_L8, _mesa_texstore_a8 },
3079 { MESA_FORMAT_I8, _mesa_texstore_a8 },
3080 { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
3081 { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
3082 { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
3083 { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
3084 { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
3085 { MESA_FORMAT_Z16, _mesa_texstore_z16 },
3086 { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
3087 { MESA_FORMAT_Z24_X8, _mesa_texstore_z24_x8 },
3088 { MESA_FORMAT_Z32, _mesa_texstore_z32 },
3089 { MESA_FORMAT_S8, NULL/*_mesa_texstore_s8*/ },
3090 { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
3091 { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 },
3092 { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 },
3093 { MESA_FORMAT_SL8, _mesa_texstore_sl8 },
3094 { MESA_FORMAT_SLA8, _mesa_texstore_sla8 },
3095 { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 },
3096 { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3097 { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3098 { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3099 { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 },
3100 { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 },
3101 { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 },
3102 { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3103 { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3104 { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3105 { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
3106 { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
3107 { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
3108 { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 },
3109 { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3110 { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3111 { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 },
3112 { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 },
3113 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3114 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3115 { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
3116 { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
3117 { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
3118 { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
3119 { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
3120 { MESA_FORMAT_SIGNED_RGBA_16, NULL },
3121 };
3122
3123
3124 static GLboolean
3125 _mesa_texstore_null(TEXSTORE_PARAMS)
3126 {
3127 (void) ctx; (void) dims;
3128 (void) baseInternalFormat;
3129 (void) dstFormat;
3130 (void) dstAddr;
3131 (void) dstXoffset; (void) dstYoffset; (void) dstZoffset;
3132 (void) dstRowStride; (void) dstImageOffsets;
3133 (void) srcWidth; (void) srcHeight; (void) srcDepth;
3134 (void) srcFormat; (void) srcType;
3135 (void) srcAddr;
3136 (void) srcPacking;
3137
3138 /* should never happen */
3139 _mesa_problem(NULL, "_mesa_texstore_null() is called");
3140 return GL_FALSE;
3141 }
3142
3143
3144 /**
3145 * Return the StoreTexImageFunc pointer to store an image in the given format.
3146 */
3147 static StoreTexImageFunc
3148 _mesa_get_texstore_func(gl_format format)
3149 {
3150 #ifdef DEBUG
3151 GLuint i;
3152 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
3153 ASSERT(texstore_funcs[i].Name == i);
3154 }
3155 #endif
3156 ASSERT(texstore_funcs[format].Name == format);
3157
3158 if (texstore_funcs[format].Store)
3159 return texstore_funcs[format].Store;
3160 else
3161 return _mesa_texstore_null;
3162 }
3163
3164
3165 /**
3166 * Store user data into texture memory.
3167 * Called via glTex[Sub]Image1/2/3D()
3168 */
3169 GLboolean
3170 _mesa_texstore(TEXSTORE_PARAMS)
3171 {
3172 StoreTexImageFunc storeImage;
3173 GLboolean success;
3174
3175 storeImage = _mesa_get_texstore_func(dstFormat);
3176
3177 success = storeImage(ctx, dims, baseInternalFormat,
3178 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3179 dstRowStride, dstImageOffsets,
3180 srcWidth, srcHeight, srcDepth,
3181 srcFormat, srcType, srcAddr, srcPacking);
3182 return success;
3183 }
3184
3185
3186 /**
3187 * Check if an unpack PBO is active prior to fetching a texture image.
3188 * If so, do bounds checking and map the buffer into main memory.
3189 * Any errors detected will be recorded.
3190 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3191 */
3192 const GLvoid *
3193 _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
3194 GLsizei width, GLsizei height, GLsizei depth,
3195 GLenum format, GLenum type, const GLvoid *pixels,
3196 const struct gl_pixelstore_attrib *unpack,
3197 const char *funcName)
3198 {
3199 GLubyte *buf;
3200
3201 if (!_mesa_is_bufferobj(unpack->BufferObj)) {
3202 /* no PBO */
3203 return pixels;
3204 }
3205 if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
3206 format, type, pixels)) {
3207 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3208 return NULL;
3209 }
3210
3211 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3212 GL_READ_ONLY_ARB, unpack->BufferObj);
3213 if (!buf) {
3214 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3215 return NULL;
3216 }
3217
3218 return ADD_POINTERS(buf, pixels);
3219 }
3220
3221
3222 /**
3223 * Check if an unpack PBO is active prior to fetching a compressed texture
3224 * image.
3225 * If so, do bounds checking and map the buffer into main memory.
3226 * Any errors detected will be recorded.
3227 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3228 */
3229 const GLvoid *
3230 _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
3231 GLsizei imageSize, const GLvoid *pixels,
3232 const struct gl_pixelstore_attrib *packing,
3233 const char *funcName)
3234 {
3235 GLubyte *buf;
3236
3237 if (!_mesa_is_bufferobj(packing->BufferObj)) {
3238 /* not using a PBO - return pointer unchanged */
3239 return pixels;
3240 }
3241 if ((const GLubyte *) pixels + imageSize >
3242 ((const GLubyte *) 0) + packing->BufferObj->Size) {
3243 /* out of bounds read! */
3244 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3245 return NULL;
3246 }
3247
3248 buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3249 GL_READ_ONLY_ARB, packing->BufferObj);
3250 if (!buf) {
3251 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3252 return NULL;
3253 }
3254
3255 return ADD_POINTERS(buf, pixels);
3256 }
3257
3258
3259 /**
3260 * This function must be called after either of the validate_pbo_*_teximage()
3261 * functions. It unmaps the PBO buffer if it was mapped earlier.
3262 */
3263 void
3264 _mesa_unmap_teximage_pbo(GLcontext *ctx,
3265 const struct gl_pixelstore_attrib *unpack)
3266 {
3267 if (_mesa_is_bufferobj(unpack->BufferObj)) {
3268 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3269 unpack->BufferObj);
3270 }
3271 }
3272
3273
3274 /** Return texture size in bytes */
3275 static GLuint
3276 texture_size(const struct gl_texture_image *texImage)
3277 {
3278 GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
3279 texImage->Height, texImage->Depth);
3280 return sz;
3281 }
3282
3283
3284 /** Return row stride in bytes */
3285 static GLuint
3286 texture_row_stride(const struct gl_texture_image *texImage)
3287 {
3288 GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
3289 texImage->Width);
3290 return stride;
3291 }
3292
3293
3294
3295 /**
3296 * This is the software fallback for Driver.TexImage1D()
3297 * and Driver.CopyTexImage1D().
3298 * \sa _mesa_store_teximage2d()
3299 * Note that the width may not be the actual texture width since it may
3300 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3301 * have the actual texture size.
3302 */
3303 void
3304 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3305 GLint internalFormat,
3306 GLint width, GLint border,
3307 GLenum format, GLenum type, const GLvoid *pixels,
3308 const struct gl_pixelstore_attrib *packing,
3309 struct gl_texture_object *texObj,
3310 struct gl_texture_image *texImage)
3311 {
3312 GLuint sizeInBytes;
3313 (void) border;
3314
3315 /* allocate memory */
3316 sizeInBytes = texture_size(texImage);
3317 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3318 if (!texImage->Data) {
3319 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3320 return;
3321 }
3322
3323 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3324 pixels, packing, "glTexImage1D");
3325 if (!pixels) {
3326 /* Note: we check for a NULL image pointer here, _after_ we allocated
3327 * memory for the texture. That's what the GL spec calls for.
3328 */
3329 return;
3330 }
3331 else {
3332 const GLint dstRowStride = 0;
3333 GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
3334 texImage->TexFormat,
3335 texImage->Data,
3336 0, 0, 0, /* dstX/Y/Zoffset */
3337 dstRowStride,
3338 texImage->ImageOffsets,
3339 width, 1, 1,
3340 format, type, pixels, packing);
3341 if (!success) {
3342 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3343 }
3344 }
3345
3346 _mesa_unmap_teximage_pbo(ctx, packing);
3347 }
3348
3349
3350 /**
3351 * This is the software fallback for Driver.TexImage2D()
3352 * and Driver.CopyTexImage2D().
3353 *
3354 * This function is oriented toward storing images in main memory, rather
3355 * than VRAM. Device driver's can easily plug in their own replacement.
3356 *
3357 * Note: width and height may be pre-convolved dimensions, but
3358 * texImage->Width and texImage->Height will be post-convolved dimensions.
3359 */
3360 void
3361 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3362 GLint internalFormat,
3363 GLint width, GLint height, GLint border,
3364 GLenum format, GLenum type, const void *pixels,
3365 const struct gl_pixelstore_attrib *packing,
3366 struct gl_texture_object *texObj,
3367 struct gl_texture_image *texImage)
3368 {
3369 GLuint sizeInBytes;
3370 (void) border;
3371
3372 /* allocate memory */
3373 sizeInBytes = texture_size(texImage);
3374 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3375 if (!texImage->Data) {
3376 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3377 return;
3378 }
3379
3380 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3381 pixels, packing, "glTexImage2D");
3382 if (!pixels) {
3383 /* Note: we check for a NULL image pointer here, _after_ we allocated
3384 * memory for the texture. That's what the GL spec calls for.
3385 */
3386 return;
3387 }
3388 else {
3389 GLint dstRowStride = texture_row_stride(texImage);
3390 GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
3391 texImage->TexFormat,
3392 texImage->Data,
3393 0, 0, 0, /* dstX/Y/Zoffset */
3394 dstRowStride,
3395 texImage->ImageOffsets,
3396 width, height, 1,
3397 format, type, pixels, packing);
3398 if (!success) {
3399 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3400 }
3401 }
3402
3403 _mesa_unmap_teximage_pbo(ctx, packing);
3404 }
3405
3406
3407
3408 /**
3409 * This is the software fallback for Driver.TexImage3D()
3410 * and Driver.CopyTexImage3D().
3411 * \sa _mesa_store_teximage2d()
3412 */
3413 void
3414 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3415 GLint internalFormat,
3416 GLint width, GLint height, GLint depth, GLint border,
3417 GLenum format, GLenum type, const void *pixels,
3418 const struct gl_pixelstore_attrib *packing,
3419 struct gl_texture_object *texObj,
3420 struct gl_texture_image *texImage)
3421 {
3422 GLuint sizeInBytes;
3423 (void) border;
3424
3425 /* allocate memory */
3426 sizeInBytes = texture_size(texImage);
3427 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3428 if (!texImage->Data) {
3429 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3430 return;
3431 }
3432
3433 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3434 type, pixels, packing, "glTexImage3D");
3435 if (!pixels) {
3436 /* Note: we check for a NULL image pointer here, _after_ we allocated
3437 * memory for the texture. That's what the GL spec calls for.
3438 */
3439 return;
3440 }
3441 else {
3442 GLint dstRowStride = texture_row_stride(texImage);
3443 GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
3444 texImage->TexFormat,
3445 texImage->Data,
3446 0, 0, 0, /* dstX/Y/Zoffset */
3447 dstRowStride,
3448 texImage->ImageOffsets,
3449 width, height, depth,
3450 format, type, pixels, packing);
3451 if (!success) {
3452 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3453 }
3454 }
3455
3456 _mesa_unmap_teximage_pbo(ctx, packing);
3457 }
3458
3459
3460
3461
3462 /*
3463 * This is the software fallback for Driver.TexSubImage1D()
3464 * and Driver.CopyTexSubImage1D().
3465 */
3466 void
3467 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
3468 GLint xoffset, GLint width,
3469 GLenum format, GLenum type, const void *pixels,
3470 const struct gl_pixelstore_attrib *packing,
3471 struct gl_texture_object *texObj,
3472 struct gl_texture_image *texImage)
3473 {
3474 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3475 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3476 pixels, packing, "glTexSubImage1D");
3477 if (!pixels)
3478 return;
3479
3480 {
3481 const GLint dstRowStride = 0;
3482 GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
3483 texImage->TexFormat,
3484 texImage->Data,
3485 xoffset, 0, 0, /* offsets */
3486 dstRowStride,
3487 texImage->ImageOffsets,
3488 width, 1, 1,
3489 format, type, pixels, packing);
3490 if (!success) {
3491 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
3492 }
3493 }
3494
3495 _mesa_unmap_teximage_pbo(ctx, packing);
3496 }
3497
3498
3499
3500 /**
3501 * This is the software fallback for Driver.TexSubImage2D()
3502 * and Driver.CopyTexSubImage2D().
3503 */
3504 void
3505 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
3506 GLint xoffset, GLint yoffset,
3507 GLint width, GLint height,
3508 GLenum format, GLenum type, const void *pixels,
3509 const struct gl_pixelstore_attrib *packing,
3510 struct gl_texture_object *texObj,
3511 struct gl_texture_image *texImage)
3512 {
3513 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3514 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3515 pixels, packing, "glTexSubImage2D");
3516 if (!pixels)
3517 return;
3518
3519 {
3520 GLint dstRowStride = texture_row_stride(texImage);
3521 GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
3522 texImage->TexFormat,
3523 texImage->Data,
3524 xoffset, yoffset, 0,
3525 dstRowStride,
3526 texImage->ImageOffsets,
3527 width, height, 1,
3528 format, type, pixels, packing);
3529 if (!success) {
3530 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
3531 }
3532 }
3533
3534 _mesa_unmap_teximage_pbo(ctx, packing);
3535 }
3536
3537
3538 /*
3539 * This is the software fallback for Driver.TexSubImage3D().
3540 * and Driver.CopyTexSubImage3D().
3541 */
3542 void
3543 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
3544 GLint xoffset, GLint yoffset, GLint zoffset,
3545 GLint width, GLint height, GLint depth,
3546 GLenum format, GLenum type, const void *pixels,
3547 const struct gl_pixelstore_attrib *packing,
3548 struct gl_texture_object *texObj,
3549 struct gl_texture_image *texImage)
3550 {
3551 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3552 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3553 type, pixels, packing,
3554 "glTexSubImage3D");
3555 if (!pixels)
3556 return;
3557
3558 {
3559 GLint dstRowStride = texture_row_stride(texImage);
3560 GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
3561 texImage->TexFormat,
3562 texImage->Data,
3563 xoffset, yoffset, zoffset,
3564 dstRowStride,
3565 texImage->ImageOffsets,
3566 width, height, depth,
3567 format, type, pixels, packing);
3568 if (!success) {
3569 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
3570 }
3571 }
3572
3573 _mesa_unmap_teximage_pbo(ctx, packing);
3574 }
3575
3576
3577 /*
3578 * Fallback for Driver.CompressedTexImage1D()
3579 */
3580 void
3581 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3582 GLint internalFormat,
3583 GLint width, GLint border,
3584 GLsizei imageSize, const GLvoid *data,
3585 struct gl_texture_object *texObj,
3586 struct gl_texture_image *texImage)
3587 {
3588 /* this space intentionally left blank */
3589 (void) ctx;
3590 (void) target; (void) level;
3591 (void) internalFormat;
3592 (void) width; (void) border;
3593 (void) imageSize; (void) data;
3594 (void) texObj;
3595 (void) texImage;
3596 }
3597
3598
3599
3600 /**
3601 * Fallback for Driver.CompressedTexImage2D()
3602 */
3603 void
3604 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3605 GLint internalFormat,
3606 GLint width, GLint height, GLint border,
3607 GLsizei imageSize, const GLvoid *data,
3608 struct gl_texture_object *texObj,
3609 struct gl_texture_image *texImage)
3610 {
3611 (void) width; (void) height; (void) border;
3612
3613 /* This is pretty simple, basically just do a memcpy without worrying
3614 * about the usual image unpacking or image transfer operations.
3615 */
3616 ASSERT(texObj);
3617 ASSERT(texImage);
3618 ASSERT(texImage->Width > 0);
3619 ASSERT(texImage->Height > 0);
3620 ASSERT(texImage->Depth == 1);
3621 ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
3622
3623 /* allocate storage */
3624 texImage->Data = _mesa_alloc_texmemory(imageSize);
3625 if (!texImage->Data) {
3626 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
3627 return;
3628 }
3629
3630 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3631 &ctx->Unpack,
3632 "glCompressedTexImage2D");
3633 if (!data)
3634 return;
3635
3636 /* copy the data */
3637 MEMCPY(texImage->Data, data, imageSize);
3638
3639 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3640 }
3641
3642
3643
3644 /*
3645 * Fallback for Driver.CompressedTexImage3D()
3646 */
3647 void
3648 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3649 GLint internalFormat,
3650 GLint width, GLint height, GLint depth,
3651 GLint border,
3652 GLsizei imageSize, const GLvoid *data,
3653 struct gl_texture_object *texObj,
3654 struct gl_texture_image *texImage)
3655 {
3656 /* this space intentionally left blank */
3657 (void) ctx;
3658 (void) target; (void) level;
3659 (void) internalFormat;
3660 (void) width; (void) height; (void) depth;
3661 (void) border;
3662 (void) imageSize; (void) data;
3663 (void) texObj;
3664 (void) texImage;
3665 }
3666
3667
3668
3669 /**
3670 * Fallback for Driver.CompressedTexSubImage1D()
3671 */
3672 void
3673 _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
3674 GLint level,
3675 GLint xoffset, GLsizei width,
3676 GLenum format,
3677 GLsizei imageSize, const GLvoid *data,
3678 struct gl_texture_object *texObj,
3679 struct gl_texture_image *texImage)
3680 {
3681 /* there are no compressed 1D texture formats yet */
3682 (void) ctx;
3683 (void) target; (void) level;
3684 (void) xoffset; (void) width;
3685 (void) format;
3686 (void) imageSize; (void) data;
3687 (void) texObj;
3688 (void) texImage;
3689 }
3690
3691
3692 /**
3693 * Fallback for Driver.CompressedTexSubImage2D()
3694 */
3695 void
3696 _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
3697 GLint level,
3698 GLint xoffset, GLint yoffset,
3699 GLsizei width, GLsizei height,
3700 GLenum format,
3701 GLsizei imageSize, const GLvoid *data,
3702 struct gl_texture_object *texObj,
3703 struct gl_texture_image *texImage)
3704 {
3705 GLint bytesPerRow, destRowStride, srcRowStride;
3706 GLint i, rows;
3707 GLubyte *dest;
3708 const GLubyte *src;
3709 const gl_format texFormat = texImage->TexFormat;
3710 const GLint destWidth = texImage->Width;
3711 GLuint bw, bh;
3712
3713 _mesa_get_format_block_size(texFormat, &bw, &bh);
3714
3715 (void) level;
3716 (void) format;
3717
3718 /* these should have been caught sooner */
3719 ASSERT((width % bw) == 0 || width == 2 || width == 1);
3720 ASSERT((height % bh) == 0 || height == 2 || height == 1);
3721 ASSERT((xoffset % bw) == 0);
3722 ASSERT((yoffset % bh) == 0);
3723
3724 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3725 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3726 &ctx->Unpack,
3727 "glCompressedTexSubImage2D");
3728 if (!data)
3729 return;
3730
3731 srcRowStride = _mesa_format_row_stride(texFormat, width);
3732 src = (const GLubyte *) data;
3733
3734 destRowStride = _mesa_format_row_stride(texFormat, destWidth);
3735 dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
3736 texFormat, destWidth,
3737 (GLubyte *) texImage->Data);
3738
3739 bytesPerRow = srcRowStride; /* bytes per row of blocks */
3740 rows = height / bh; /* rows in blocks */
3741
3742 /* copy rows of blocks */
3743 for (i = 0; i < rows; i++) {
3744 MEMCPY(dest, src, bytesPerRow);
3745 dest += destRowStride;
3746 src += srcRowStride;
3747 }
3748
3749 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3750 }
3751
3752
3753 /**
3754 * Fallback for Driver.CompressedTexSubImage3D()
3755 */
3756 void
3757 _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
3758 GLint level,
3759 GLint xoffset, GLint yoffset, GLint zoffset,
3760 GLsizei width, GLsizei height, GLsizei depth,
3761 GLenum format,
3762 GLsizei imageSize, const GLvoid *data,
3763 struct gl_texture_object *texObj,
3764 struct gl_texture_image *texImage)
3765 {
3766 /* there are no compressed 3D texture formats yet */
3767 (void) ctx;
3768 (void) target; (void) level;
3769 (void) xoffset; (void) yoffset; (void) zoffset;
3770 (void) width; (void) height; (void) depth;
3771 (void) format;
3772 (void) imageSize; (void) data;
3773 (void) texObj;
3774 (void) texImage;
3775 }