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