mesa: remove old, unused #define
[mesa.git] / src / mesa / main / texstore.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 7.5
4 *
5 * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
6 * Copyright (c) 2008-2009 VMware, Inc.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included
16 * in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
22 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26 /*
27 * Authors:
28 * Brian Paul
29 */
30
31 /**
32 * The GL texture image functions in teximage.c basically just do
33 * error checking and data structure allocation. They in turn call
34 * device driver functions which actually copy/convert/store the user's
35 * texture image data.
36 *
37 * However, most device drivers will be able to use the fallback functions
38 * in this file. That is, most drivers will have the following bit of
39 * code:
40 * ctx->Driver.TexImage1D = _mesa_store_teximage1d;
41 * ctx->Driver.TexImage2D = _mesa_store_teximage2d;
42 * ctx->Driver.TexImage3D = _mesa_store_teximage3d;
43 * etc...
44 *
45 * Texture image processing is actually kind of complicated. We have to do:
46 * Format/type conversions
47 * pixel unpacking
48 * pixel transfer (scale, bais, lookup, convolution!, etc)
49 *
50 * These functions can handle most everything, including processing full
51 * images and sub-images.
52 */
53
54
55 #include "glheader.h"
56 #include "bufferobj.h"
57 #include "colormac.h"
58 #include "context.h"
59 #include "convolve.h"
60 #include "image.h"
61 #include "macros.h"
62 #include "mipmap.h"
63 #include "imports.h"
64 #include "texcompress.h"
65 #include "texcompress_fxt1.h"
66 #include "texcompress_s3tc.h"
67 #include "teximage.h"
68 #include "texstore.h"
69 #include "enums.h"
70
71
72 enum {
73 ZERO = 4,
74 ONE = 5
75 };
76
77
78 /**
79 * Texture image storage function.
80 */
81 typedef GLboolean (*StoreTexImageFunc)(TEXSTORE_PARAMS);
82
83
84 /**
85 * Return GL_TRUE if the given image format is one that be converted
86 * to another format by swizzling.
87 */
88 static GLboolean
89 can_swizzle(GLenum logicalBaseFormat)
90 {
91 switch (logicalBaseFormat) {
92 case GL_RGBA:
93 case GL_RGB:
94 case GL_LUMINANCE_ALPHA:
95 case GL_INTENSITY:
96 case GL_ALPHA:
97 case GL_LUMINANCE:
98 case GL_RED:
99 case GL_GREEN:
100 case GL_BLUE:
101 case GL_BGR:
102 case GL_BGRA:
103 case GL_ABGR_EXT:
104 return GL_TRUE;
105 default:
106 return GL_FALSE;
107 }
108 }
109
110
111
112 enum {
113 IDX_LUMINANCE = 0,
114 IDX_ALPHA,
115 IDX_INTENSITY,
116 IDX_LUMINANCE_ALPHA,
117 IDX_RGB,
118 IDX_RGBA,
119 IDX_RED,
120 IDX_GREEN,
121 IDX_BLUE,
122 IDX_BGR,
123 IDX_BGRA,
124 IDX_ABGR,
125 MAX_IDX
126 };
127
128 #define MAP1(x) MAP4(x, ZERO, ZERO, ZERO)
129 #define MAP2(x,y) MAP4(x, y, ZERO, ZERO)
130 #define MAP3(x,y,z) MAP4(x, y, z, ZERO)
131 #define MAP4(x,y,z,w) { x, y, z, w, ZERO, ONE }
132
133
134 static const struct {
135 GLubyte format_idx;
136 GLubyte to_rgba[6];
137 GLubyte from_rgba[6];
138 } mappings[MAX_IDX] =
139 {
140 {
141 IDX_LUMINANCE,
142 MAP4(0,0,0,ONE),
143 MAP1(0)
144 },
145
146 {
147 IDX_ALPHA,
148 MAP4(ZERO, ZERO, ZERO, 0),
149 MAP1(3)
150 },
151
152 {
153 IDX_INTENSITY,
154 MAP4(0, 0, 0, 0),
155 MAP1(0),
156 },
157
158 {
159 IDX_LUMINANCE_ALPHA,
160 MAP4(0,0,0,1),
161 MAP2(0,3)
162 },
163
164 {
165 IDX_RGB,
166 MAP4(0,1,2,ONE),
167 MAP3(0,1,2)
168 },
169
170 {
171 IDX_RGBA,
172 MAP4(0,1,2,3),
173 MAP4(0,1,2,3),
174 },
175
176
177 {
178 IDX_RED,
179 MAP4(0, ZERO, ZERO, ONE),
180 MAP1(0),
181 },
182
183 {
184 IDX_GREEN,
185 MAP4(ZERO, 0, ZERO, ONE),
186 MAP1(1),
187 },
188
189 {
190 IDX_BLUE,
191 MAP4(ZERO, ZERO, 0, ONE),
192 MAP1(2),
193 },
194
195 {
196 IDX_BGR,
197 MAP4(2,1,0,ONE),
198 MAP3(2,1,0)
199 },
200
201 {
202 IDX_BGRA,
203 MAP4(2,1,0,3),
204 MAP4(2,1,0,3)
205 },
206
207 {
208 IDX_ABGR,
209 MAP4(3,2,1,0),
210 MAP4(3,2,1,0)
211 },
212 };
213
214
215
216 /**
217 * Convert a GL image format enum to an IDX_* value (see above).
218 */
219 static int
220 get_map_idx(GLenum value)
221 {
222 switch (value) {
223 case GL_LUMINANCE: return IDX_LUMINANCE;
224 case GL_ALPHA: return IDX_ALPHA;
225 case GL_INTENSITY: return IDX_INTENSITY;
226 case GL_LUMINANCE_ALPHA: return IDX_LUMINANCE_ALPHA;
227 case GL_RGB: return IDX_RGB;
228 case GL_RGBA: return IDX_RGBA;
229 case GL_RED: return IDX_RED;
230 case GL_GREEN: return IDX_GREEN;
231 case GL_BLUE: return IDX_BLUE;
232 case GL_BGR: return IDX_BGR;
233 case GL_BGRA: return IDX_BGRA;
234 case GL_ABGR_EXT: return IDX_ABGR;
235 default:
236 _mesa_problem(NULL, "Unexpected inFormat");
237 return 0;
238 }
239 }
240
241
242 /**
243 * When promoting texture formats (see below) we need to compute the
244 * mapping of dest components back to source components.
245 * This function does that.
246 * \param inFormat the incoming format of the texture
247 * \param outFormat the final texture format
248 * \return map[6] a full 6-component map
249 */
250 static void
251 compute_component_mapping(GLenum inFormat, GLenum outFormat,
252 GLubyte *map)
253 {
254 const int inFmt = get_map_idx(inFormat);
255 const int outFmt = get_map_idx(outFormat);
256 const GLubyte *in2rgba = mappings[inFmt].to_rgba;
257 const GLubyte *rgba2out = mappings[outFmt].from_rgba;
258 int i;
259
260 for (i = 0; i < 4; i++)
261 map[i] = in2rgba[rgba2out[i]];
262
263 map[ZERO] = ZERO;
264 map[ONE] = ONE;
265
266 /*
267 _mesa_printf("from %x/%s to %x/%s map %d %d %d %d %d %d\n",
268 inFormat, _mesa_lookup_enum_by_nr(inFormat),
269 outFormat, _mesa_lookup_enum_by_nr(outFormat),
270 map[0],
271 map[1],
272 map[2],
273 map[3],
274 map[4],
275 map[5]);
276 */
277 }
278
279
280 #if !FEATURE_convolve
281 static void
282 _mesa_adjust_image_for_convolution(GLcontext *ctx, GLuint dims,
283 GLsizei *srcWidth, GLsizei *srcHeight)
284 {
285 /* no-op */
286 }
287 #endif
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, 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(GLcontext *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 {
322 GLuint transferOps = ctx->_ImageTransferState;
323 GLfloat *tempImage;
324
325 ASSERT(dims >= 1 && dims <= 3);
326
327 ASSERT(logicalBaseFormat == GL_RGBA ||
328 logicalBaseFormat == GL_RGB ||
329 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
330 logicalBaseFormat == GL_LUMINANCE ||
331 logicalBaseFormat == GL_ALPHA ||
332 logicalBaseFormat == GL_INTENSITY ||
333 logicalBaseFormat == GL_COLOR_INDEX ||
334 logicalBaseFormat == GL_DEPTH_COMPONENT);
335
336 ASSERT(textureBaseFormat == GL_RGBA ||
337 textureBaseFormat == GL_RGB ||
338 textureBaseFormat == GL_LUMINANCE_ALPHA ||
339 textureBaseFormat == GL_LUMINANCE ||
340 textureBaseFormat == GL_ALPHA ||
341 textureBaseFormat == GL_INTENSITY ||
342 textureBaseFormat == GL_COLOR_INDEX ||
343 textureBaseFormat == GL_DEPTH_COMPONENT);
344
345 /* conventional color image */
346
347 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
348 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
349 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
350 /* need image convolution */
351 const GLuint preConvTransferOps
352 = (transferOps & IMAGE_PRE_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
353 const GLuint postConvTransferOps
354 = (transferOps & IMAGE_POST_CONVOLUTION_BITS) | IMAGE_CLAMP_BIT;
355 GLint img, row;
356 GLint convWidth, convHeight;
357 GLfloat *convImage;
358
359 /* pre-convolution image buffer (3D) */
360 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
361 * 4 * sizeof(GLfloat));
362 if (!tempImage)
363 return NULL;
364
365 /* post-convolution image buffer (2D) */
366 convImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight
367 * 4 * sizeof(GLfloat));
368 if (!convImage) {
369 _mesa_free(tempImage);
370 return NULL;
371 }
372
373 /* loop over 3D image slices */
374 for (img = 0; img < srcDepth; img++) {
375 GLfloat *dst = tempImage + img * (srcWidth * srcHeight * 4);
376
377 /* unpack and do transfer ops up to convolution */
378 for (row = 0; row < srcHeight; row++) {
379 const GLvoid *src = _mesa_image_address(dims, srcPacking,
380 srcAddr, srcWidth, srcHeight,
381 srcFormat, srcType, img, row, 0);
382 _mesa_unpack_color_span_float(ctx, srcWidth, GL_RGBA, dst,
383 srcFormat, srcType, src,
384 srcPacking,
385 preConvTransferOps);
386 dst += srcWidth * 4;
387 }
388
389 /* size after optional convolution */
390 convWidth = srcWidth;
391 convHeight = srcHeight;
392
393 #if FEATURE_convolve
394 /* do convolution */
395 {
396 GLfloat *src = tempImage + img * (srcWidth * srcHeight * 4);
397 if (dims == 1) {
398 ASSERT(ctx->Pixel.Convolution1DEnabled);
399 _mesa_convolve_1d_image(ctx, &convWidth, src, convImage);
400 }
401 else {
402 if (ctx->Pixel.Convolution2DEnabled) {
403 _mesa_convolve_2d_image(ctx, &convWidth, &convHeight,
404 src, convImage);
405 }
406 else {
407 ASSERT(ctx->Pixel.Separable2DEnabled);
408 _mesa_convolve_sep_image(ctx, &convWidth, &convHeight,
409 src, convImage);
410 }
411 }
412 }
413 #endif
414 /* do post-convolution transfer and pack into tempImage */
415 {
416 const GLint logComponents
417 = _mesa_components_in_format(logicalBaseFormat);
418 const GLfloat *src = convImage;
419 GLfloat *dst = tempImage + img * (convWidth * convHeight * 4);
420 for (row = 0; row < convHeight; row++) {
421 _mesa_pack_rgba_span_float(ctx, convWidth,
422 (GLfloat (*)[4]) src,
423 logicalBaseFormat, GL_FLOAT,
424 dst, &ctx->DefaultPacking,
425 postConvTransferOps);
426 src += convWidth * 4;
427 dst += convWidth * logComponents;
428 }
429 }
430 } /* loop over 3D image slices */
431
432 _mesa_free(convImage);
433
434 /* might need these below */
435 srcWidth = convWidth;
436 srcHeight = convHeight;
437 }
438 else {
439 /* no convolution */
440 const GLint components = _mesa_components_in_format(logicalBaseFormat);
441 const GLint srcStride =
442 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
443 GLfloat *dst;
444 GLint img, row;
445
446 tempImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
447 * components * sizeof(GLfloat));
448 if (!tempImage)
449 return NULL;
450
451 dst = tempImage;
452 for (img = 0; img < srcDepth; img++) {
453 const GLubyte *src
454 = (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
455 srcWidth, srcHeight,
456 srcFormat, srcType,
457 img, 0, 0);
458 for (row = 0; row < srcHeight; row++) {
459 _mesa_unpack_color_span_float(ctx, srcWidth, logicalBaseFormat,
460 dst, srcFormat, srcType, src,
461 srcPacking, transferOps);
462 dst += srcWidth * components;
463 src += srcStride;
464 }
465 }
466 }
467
468 if (logicalBaseFormat != textureBaseFormat) {
469 /* more work */
470 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
471 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
472 GLfloat *newImage;
473 GLint i, n;
474 GLubyte map[6];
475
476 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
477 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
478 textureBaseFormat == GL_LUMINANCE_ALPHA);
479
480 /* The actual texture format should have at least as many components
481 * as the logical texture format.
482 */
483 ASSERT(texComponents >= logComponents);
484
485 newImage = (GLfloat *) _mesa_malloc(srcWidth * srcHeight * srcDepth
486 * texComponents * sizeof(GLfloat));
487 if (!newImage) {
488 _mesa_free(tempImage);
489 return NULL;
490 }
491
492 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
493
494 n = srcWidth * srcHeight * srcDepth;
495 for (i = 0; i < n; i++) {
496 GLint k;
497 for (k = 0; k < texComponents; k++) {
498 GLint j = map[k];
499 if (j == ZERO)
500 newImage[i * texComponents + k] = 0.0F;
501 else if (j == ONE)
502 newImage[i * texComponents + k] = 1.0F;
503 else
504 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
505 }
506 }
507
508 _mesa_free(tempImage);
509 tempImage = newImage;
510 }
511
512 return tempImage;
513 }
514
515
516 /**
517 * Make a temporary (color) texture image with GLchan components.
518 * Apply all needed pixel unpacking and pixel transfer operations.
519 * Note that there are both logicalBaseFormat and textureBaseFormat parameters.
520 * Suppose the user specifies GL_LUMINANCE as the internal texture format
521 * but the graphics hardware doesn't support luminance textures. So, might
522 * use an RGB hardware format instead.
523 * If logicalBaseFormat != textureBaseFormat we have some extra work to do.
524 *
525 * \param ctx the rendering context
526 * \param dims image dimensions: 1, 2 or 3
527 * \param logicalBaseFormat basic texture derived from the user's
528 * internal texture format value
529 * \param textureBaseFormat the actual basic format of the texture
530 * \param srcWidth source image width
531 * \param srcHeight source image height
532 * \param srcDepth source image depth
533 * \param srcFormat source image format
534 * \param srcType source image type
535 * \param srcAddr source image address
536 * \param srcPacking source image pixel packing
537 * \return resulting image with format = textureBaseFormat and type = GLchan.
538 */
539 GLchan *
540 _mesa_make_temp_chan_image(GLcontext *ctx, GLuint dims,
541 GLenum logicalBaseFormat,
542 GLenum textureBaseFormat,
543 GLint srcWidth, GLint srcHeight, GLint srcDepth,
544 GLenum srcFormat, GLenum srcType,
545 const GLvoid *srcAddr,
546 const struct gl_pixelstore_attrib *srcPacking)
547 {
548 GLuint transferOps = ctx->_ImageTransferState;
549 const GLint components = _mesa_components_in_format(logicalBaseFormat);
550 GLboolean freeSrcImage = GL_FALSE;
551 GLint img, row;
552 GLchan *tempImage, *dst;
553
554 ASSERT(dims >= 1 && dims <= 3);
555
556 ASSERT(logicalBaseFormat == GL_RGBA ||
557 logicalBaseFormat == GL_RGB ||
558 logicalBaseFormat == GL_LUMINANCE_ALPHA ||
559 logicalBaseFormat == GL_LUMINANCE ||
560 logicalBaseFormat == GL_ALPHA ||
561 logicalBaseFormat == GL_INTENSITY);
562
563 ASSERT(textureBaseFormat == GL_RGBA ||
564 textureBaseFormat == GL_RGB ||
565 textureBaseFormat == GL_LUMINANCE_ALPHA ||
566 textureBaseFormat == GL_LUMINANCE ||
567 textureBaseFormat == GL_ALPHA ||
568 textureBaseFormat == GL_INTENSITY);
569
570 #if FEATURE_convolve
571 if ((dims == 1 && ctx->Pixel.Convolution1DEnabled) ||
572 (dims >= 2 && ctx->Pixel.Convolution2DEnabled) ||
573 (dims >= 2 && ctx->Pixel.Separable2DEnabled)) {
574 /* get convolved image */
575 GLfloat *convImage = make_temp_float_image(ctx, dims,
576 logicalBaseFormat,
577 logicalBaseFormat,
578 srcWidth, srcHeight, srcDepth,
579 srcFormat, srcType,
580 srcAddr, srcPacking);
581 if (!convImage)
582 return NULL;
583 /* the convolved image is our new source image */
584 srcAddr = convImage;
585 srcFormat = logicalBaseFormat;
586 srcType = GL_FLOAT;
587 srcPacking = &ctx->DefaultPacking;
588 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
589 transferOps = 0;
590 freeSrcImage = GL_TRUE;
591 }
592 #endif
593
594 /* unpack and transfer the source image */
595 tempImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
596 * components * sizeof(GLchan));
597 if (!tempImage) {
598 if (freeSrcImage) {
599 _mesa_free((void *) srcAddr);
600 }
601 return NULL;
602 }
603
604 dst = tempImage;
605 for (img = 0; img < srcDepth; img++) {
606 const GLint srcStride =
607 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
608 const GLubyte *src =
609 (const GLubyte *) _mesa_image_address(dims, srcPacking, srcAddr,
610 srcWidth, srcHeight,
611 srcFormat, srcType,
612 img, 0, 0);
613 for (row = 0; row < srcHeight; row++) {
614 _mesa_unpack_color_span_chan(ctx, srcWidth, logicalBaseFormat, dst,
615 srcFormat, srcType, src, srcPacking,
616 transferOps);
617 dst += srcWidth * components;
618 src += srcStride;
619 }
620 }
621
622 /* If we made a temporary image for convolution, free it here */
623 if (freeSrcImage) {
624 _mesa_free((void *) srcAddr);
625 }
626
627 if (logicalBaseFormat != textureBaseFormat) {
628 /* one more conversion step */
629 GLint texComponents = _mesa_components_in_format(textureBaseFormat);
630 GLint logComponents = _mesa_components_in_format(logicalBaseFormat);
631 GLchan *newImage;
632 GLint i, n;
633 GLubyte map[6];
634
635 /* we only promote up to RGB, RGBA and LUMINANCE_ALPHA formats for now */
636 ASSERT(textureBaseFormat == GL_RGB || textureBaseFormat == GL_RGBA ||
637 textureBaseFormat == GL_LUMINANCE_ALPHA);
638
639 /* The actual texture format should have at least as many components
640 * as the logical texture format.
641 */
642 ASSERT(texComponents >= logComponents);
643
644 newImage = (GLchan *) _mesa_malloc(srcWidth * srcHeight * srcDepth
645 * texComponents * sizeof(GLchan));
646 if (!newImage) {
647 _mesa_free(tempImage);
648 return NULL;
649 }
650
651 compute_component_mapping(logicalBaseFormat, textureBaseFormat, map);
652
653 n = srcWidth * srcHeight * srcDepth;
654 for (i = 0; i < n; i++) {
655 GLint k;
656 for (k = 0; k < texComponents; k++) {
657 GLint j = map[k];
658 if (j == ZERO)
659 newImage[i * texComponents + k] = 0;
660 else if (j == ONE)
661 newImage[i * texComponents + k] = CHAN_MAX;
662 else
663 newImage[i * texComponents + k] = tempImage[i * logComponents + j];
664 }
665 }
666
667 _mesa_free(tempImage);
668 tempImage = newImage;
669 }
670
671 return tempImage;
672 }
673
674
675 /**
676 * Copy GLubyte pixels from <src> to <dst> with swizzling.
677 * \param dst destination pixels
678 * \param dstComponents number of color components in destination pixels
679 * \param src source pixels
680 * \param srcComponents number of color components in source pixels
681 * \param map the swizzle mapping. map[X] says where to find the X component
682 * in the source image's pixels. For example, if the source image
683 * is GL_BGRA and X = red, map[0] yields 2.
684 * \param count number of pixels to copy/swizzle.
685 */
686 static void
687 swizzle_copy(GLubyte *dst, GLuint dstComponents, const GLubyte *src,
688 GLuint srcComponents, const GLubyte *map, GLuint count)
689 {
690 #define SWZ_CPY(dst, src, count, dstComps, srcComps) \
691 do { \
692 GLuint i; \
693 for (i = 0; i < count; i++) { \
694 GLuint j; \
695 if (srcComps == 4) { \
696 COPY_4UBV(tmp, src); \
697 } \
698 else { \
699 for (j = 0; j < srcComps; j++) { \
700 tmp[j] = src[j]; \
701 } \
702 } \
703 src += srcComps; \
704 for (j = 0; j < dstComps; j++) { \
705 dst[j] = tmp[map[j]]; \
706 } \
707 dst += dstComps; \
708 } \
709 } while (0)
710
711 GLubyte tmp[6];
712
713 tmp[ZERO] = 0x0;
714 tmp[ONE] = 0xff;
715
716 ASSERT(srcComponents <= 4);
717 ASSERT(dstComponents <= 4);
718
719 switch (dstComponents) {
720 case 4:
721 switch (srcComponents) {
722 case 4:
723 SWZ_CPY(dst, src, count, 4, 4);
724 break;
725 case 3:
726 SWZ_CPY(dst, src, count, 4, 3);
727 break;
728 case 2:
729 SWZ_CPY(dst, src, count, 4, 2);
730 break;
731 case 1:
732 SWZ_CPY(dst, src, count, 4, 1);
733 break;
734 default:
735 ;
736 }
737 break;
738 case 3:
739 switch (srcComponents) {
740 case 4:
741 SWZ_CPY(dst, src, count, 3, 4);
742 break;
743 case 3:
744 SWZ_CPY(dst, src, count, 3, 3);
745 break;
746 case 2:
747 SWZ_CPY(dst, src, count, 3, 2);
748 break;
749 case 1:
750 SWZ_CPY(dst, src, count, 3, 1);
751 break;
752 default:
753 ;
754 }
755 break;
756 case 2:
757 switch (srcComponents) {
758 case 4:
759 SWZ_CPY(dst, src, count, 2, 4);
760 break;
761 case 3:
762 SWZ_CPY(dst, src, count, 2, 3);
763 break;
764 case 2:
765 SWZ_CPY(dst, src, count, 2, 2);
766 break;
767 case 1:
768 SWZ_CPY(dst, src, count, 2, 1);
769 break;
770 default:
771 ;
772 }
773 break;
774 case 1:
775 switch (srcComponents) {
776 case 4:
777 SWZ_CPY(dst, src, count, 1, 4);
778 break;
779 case 3:
780 SWZ_CPY(dst, src, count, 1, 3);
781 break;
782 case 2:
783 SWZ_CPY(dst, src, count, 1, 2);
784 break;
785 case 1:
786 SWZ_CPY(dst, src, count, 1, 1);
787 break;
788 default:
789 ;
790 }
791 break;
792 default:
793 ;
794 }
795 #undef SWZ_CPY
796 }
797
798
799
800 static const GLubyte map_identity[6] = { 0, 1, 2, 3, ZERO, ONE };
801 static const GLubyte map_3210[6] = { 3, 2, 1, 0, ZERO, ONE };
802
803 /* Deal with the _REV input types:
804 */
805 static const GLubyte *
806 type_mapping( GLenum srcType )
807 {
808 switch (srcType) {
809 case GL_BYTE:
810 case GL_UNSIGNED_BYTE:
811 return map_identity;
812 case GL_UNSIGNED_INT_8_8_8_8:
813 return _mesa_little_endian() ? map_3210 : map_identity;
814 case GL_UNSIGNED_INT_8_8_8_8_REV:
815 return _mesa_little_endian() ? map_identity : map_3210;
816 default:
817 return NULL;
818 }
819 }
820
821 /* Mapping required if input type is
822 */
823 static const GLubyte *
824 byteswap_mapping( GLboolean swapBytes,
825 GLenum srcType )
826 {
827 if (!swapBytes)
828 return map_identity;
829
830 switch (srcType) {
831 case GL_BYTE:
832 case GL_UNSIGNED_BYTE:
833 return map_identity;
834 case GL_UNSIGNED_INT_8_8_8_8:
835 case GL_UNSIGNED_INT_8_8_8_8_REV:
836 return map_3210;
837 default:
838 return NULL;
839 }
840 }
841
842
843
844 /**
845 * Transfer a GLubyte texture image with component swizzling.
846 */
847 static void
848 _mesa_swizzle_ubyte_image(GLcontext *ctx,
849 GLuint dimensions,
850 GLenum srcFormat,
851 GLenum srcType,
852
853 GLenum baseInternalFormat,
854
855 const GLubyte *rgba2dst,
856 GLuint dstComponents,
857
858 GLvoid *dstAddr,
859 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
860 GLint dstRowStride,
861 const GLuint *dstImageOffsets,
862
863 GLint srcWidth, GLint srcHeight, GLint srcDepth,
864 const GLvoid *srcAddr,
865 const struct gl_pixelstore_attrib *srcPacking )
866 {
867 GLint srcComponents = _mesa_components_in_format(srcFormat);
868 const GLubyte *srctype2ubyte, *swap;
869 GLubyte map[4], src2base[6], base2rgba[6];
870 GLint i;
871 const GLint srcRowStride =
872 _mesa_image_row_stride(srcPacking, srcWidth,
873 srcFormat, GL_UNSIGNED_BYTE);
874 const GLint srcImageStride
875 = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat,
876 GL_UNSIGNED_BYTE);
877 const GLubyte *srcImage
878 = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr,
879 srcWidth, srcHeight, srcFormat,
880 GL_UNSIGNED_BYTE, 0, 0, 0);
881
882 (void) ctx;
883
884 /* Translate from src->baseInternal->GL_RGBA->dst. This will
885 * correctly deal with RGBA->RGB->RGBA conversions where the final
886 * A value must be 0xff regardless of the incoming alpha values.
887 */
888 compute_component_mapping(srcFormat, baseInternalFormat, src2base);
889 compute_component_mapping(baseInternalFormat, GL_RGBA, base2rgba);
890 swap = byteswap_mapping(srcPacking->SwapBytes, srcType);
891 srctype2ubyte = type_mapping(srcType);
892
893
894 for (i = 0; i < 4; i++)
895 map[i] = srctype2ubyte[swap[src2base[base2rgba[rgba2dst[i]]]]];
896
897 /* _mesa_printf("map %d %d %d %d\n", map[0], map[1], map[2], map[3]); */
898
899 if (srcComponents == dstComponents &&
900 srcRowStride == dstRowStride &&
901 srcRowStride == srcWidth * srcComponents &&
902 dimensions < 3) {
903 /* 1 and 2D images only */
904 GLubyte *dstImage = (GLubyte *) dstAddr
905 + dstYoffset * dstRowStride
906 + dstXoffset * dstComponents;
907 swizzle_copy(dstImage, dstComponents, srcImage, srcComponents, map,
908 srcWidth * srcHeight);
909 }
910 else {
911 GLint img, row;
912 for (img = 0; img < srcDepth; img++) {
913 const GLubyte *srcRow = srcImage;
914 GLubyte *dstRow = (GLubyte *) dstAddr
915 + dstImageOffsets[dstZoffset + img] * dstComponents
916 + dstYoffset * dstRowStride
917 + dstXoffset * dstComponents;
918 for (row = 0; row < srcHeight; row++) {
919 swizzle_copy(dstRow, dstComponents, srcRow, srcComponents, map, srcWidth);
920 dstRow += dstRowStride;
921 srcRow += srcRowStride;
922 }
923 srcImage += srcImageStride;
924 }
925 }
926 }
927
928
929 /**
930 * Teximage storage routine for when a simple memcpy will do.
931 * No pixel transfer operations or special texel encodings allowed.
932 * 1D, 2D and 3D images supported.
933 */
934 static void
935 memcpy_texture(GLcontext *ctx,
936 GLuint dimensions,
937 gl_format dstFormat,
938 GLvoid *dstAddr,
939 GLint dstXoffset, GLint dstYoffset, GLint dstZoffset,
940 GLint dstRowStride,
941 const GLuint *dstImageOffsets,
942 GLint srcWidth, GLint srcHeight, GLint srcDepth,
943 GLenum srcFormat, GLenum srcType,
944 const GLvoid *srcAddr,
945 const struct gl_pixelstore_attrib *srcPacking)
946 {
947 const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth,
948 srcFormat, srcType);
949 const GLint srcImageStride = _mesa_image_image_stride(srcPacking,
950 srcWidth, srcHeight, srcFormat, srcType);
951 const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions,
952 srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0);
953 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
954 const GLint bytesPerRow = srcWidth * texelBytes;
955
956 #if 0
957 /* XXX update/re-enable for dstImageOffsets array */
958 const GLint bytesPerImage = srcHeight * bytesPerRow;
959 const GLint bytesPerTexture = srcDepth * bytesPerImage;
960 GLubyte *dstImage = (GLubyte *) dstAddr
961 + dstZoffset * dstImageStride
962 + dstYoffset * dstRowStride
963 + dstXoffset * texelBytes;
964
965 if (dstRowStride == srcRowStride &&
966 dstRowStride == bytesPerRow &&
967 ((dstImageStride == srcImageStride &&
968 dstImageStride == bytesPerImage) ||
969 (srcDepth == 1))) {
970 /* one big memcpy */
971 ctx->Driver.TextureMemCpy(dstImage, srcImage, bytesPerTexture);
972 }
973 else
974 {
975 GLint img, row;
976 for (img = 0; img < srcDepth; img++) {
977 const GLubyte *srcRow = srcImage;
978 GLubyte *dstRow = dstImage;
979 for (row = 0; row < srcHeight; row++) {
980 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
981 dstRow += dstRowStride;
982 srcRow += srcRowStride;
983 }
984 srcImage += srcImageStride;
985 dstImage += dstImageStride;
986 }
987 }
988 #endif
989
990 GLint img, row;
991 for (img = 0; img < srcDepth; img++) {
992 const GLubyte *srcRow = srcImage;
993 GLubyte *dstRow = (GLubyte *) dstAddr
994 + dstImageOffsets[dstZoffset + img] * texelBytes
995 + dstYoffset * dstRowStride
996 + dstXoffset * texelBytes;
997 for (row = 0; row < srcHeight; row++) {
998 ctx->Driver.TextureMemCpy(dstRow, srcRow, bytesPerRow);
999 dstRow += dstRowStride;
1000 srcRow += srcRowStride;
1001 }
1002 srcImage += srcImageStride;
1003 }
1004 }
1005
1006
1007
1008 /**
1009 * Store a 32-bit integer depth component texture image.
1010 */
1011 static GLboolean
1012 _mesa_texstore_z32(TEXSTORE_PARAMS)
1013 {
1014 const GLuint depthScale = 0xffffffff;
1015 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1016 (void) dims;
1017 ASSERT(dstFormat == MESA_FORMAT_Z32);
1018 ASSERT(texelBytes == sizeof(GLuint));
1019
1020 if (ctx->Pixel.DepthScale == 1.0f &&
1021 ctx->Pixel.DepthBias == 0.0f &&
1022 !srcPacking->SwapBytes &&
1023 baseInternalFormat == GL_DEPTH_COMPONENT &&
1024 srcFormat == GL_DEPTH_COMPONENT &&
1025 srcType == GL_UNSIGNED_INT) {
1026 /* simple memcpy path */
1027 memcpy_texture(ctx, dims,
1028 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1029 dstRowStride,
1030 dstImageOffsets,
1031 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1032 srcAddr, srcPacking);
1033 }
1034 else {
1035 /* general path */
1036 GLint img, row;
1037 for (img = 0; img < srcDepth; img++) {
1038 GLubyte *dstRow = (GLubyte *) dstAddr
1039 + dstImageOffsets[dstZoffset + img] * texelBytes
1040 + dstYoffset * dstRowStride
1041 + dstXoffset * texelBytes;
1042 for (row = 0; row < srcHeight; row++) {
1043 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1044 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1045 _mesa_unpack_depth_span(ctx, srcWidth,
1046 GL_UNSIGNED_INT, (GLuint *) dstRow,
1047 depthScale, srcType, src, srcPacking);
1048 dstRow += dstRowStride;
1049 }
1050 }
1051 }
1052 return GL_TRUE;
1053 }
1054
1055
1056 /**
1057 * Store a 24-bit integer depth component texture image.
1058 */
1059 static GLboolean
1060 _mesa_texstore_x8_z24(TEXSTORE_PARAMS)
1061 {
1062 const GLuint depthScale = 0xffffff;
1063 const GLuint texelBytes = 4;
1064
1065 (void) dims;
1066 ASSERT(dstFormat == MESA_FORMAT_X8_Z24);
1067
1068 {
1069 /* general path */
1070 GLint img, row;
1071 for (img = 0; img < srcDepth; img++) {
1072 GLubyte *dstRow = (GLubyte *) dstAddr
1073 + dstImageOffsets[dstZoffset + img] * texelBytes
1074 + dstYoffset * dstRowStride
1075 + dstXoffset * texelBytes;
1076 for (row = 0; row < srcHeight; row++) {
1077 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1078 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1079 _mesa_unpack_depth_span(ctx, srcWidth,
1080 GL_UNSIGNED_INT, (GLuint *) dstRow,
1081 depthScale, srcType, src, srcPacking);
1082 dstRow += dstRowStride;
1083 }
1084 }
1085 }
1086 return GL_TRUE;
1087 }
1088
1089
1090 /**
1091 * Store a 16-bit integer depth component texture image.
1092 */
1093 static GLboolean
1094 _mesa_texstore_z16(TEXSTORE_PARAMS)
1095 {
1096 const GLuint depthScale = 0xffff;
1097 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1098 (void) dims;
1099 ASSERT(dstFormat == MESA_FORMAT_Z16);
1100 ASSERT(texelBytes == sizeof(GLushort));
1101
1102 if (ctx->Pixel.DepthScale == 1.0f &&
1103 ctx->Pixel.DepthBias == 0.0f &&
1104 !srcPacking->SwapBytes &&
1105 baseInternalFormat == GL_DEPTH_COMPONENT &&
1106 srcFormat == GL_DEPTH_COMPONENT &&
1107 srcType == GL_UNSIGNED_SHORT) {
1108 /* simple memcpy path */
1109 memcpy_texture(ctx, dims,
1110 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1111 dstRowStride,
1112 dstImageOffsets,
1113 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1114 srcAddr, srcPacking);
1115 }
1116 else {
1117 /* general path */
1118 GLint img, row;
1119 for (img = 0; img < srcDepth; img++) {
1120 GLubyte *dstRow = (GLubyte *) dstAddr
1121 + dstImageOffsets[dstZoffset + img] * texelBytes
1122 + dstYoffset * dstRowStride
1123 + dstXoffset * texelBytes;
1124 for (row = 0; row < srcHeight; row++) {
1125 const GLvoid *src = _mesa_image_address(dims, srcPacking,
1126 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
1127 GLushort *dst16 = (GLushort *) dstRow;
1128 _mesa_unpack_depth_span(ctx, srcWidth,
1129 GL_UNSIGNED_SHORT, dst16, depthScale,
1130 srcType, src, srcPacking);
1131 dstRow += dstRowStride;
1132 }
1133 }
1134 }
1135 return GL_TRUE;
1136 }
1137
1138
1139 /**
1140 * Store an rgb565 or rgb565_rev texture image.
1141 */
1142 static GLboolean
1143 _mesa_texstore_rgb565(TEXSTORE_PARAMS)
1144 {
1145 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1146 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1147
1148 ASSERT(dstFormat == MESA_FORMAT_RGB565 ||
1149 dstFormat == MESA_FORMAT_RGB565_REV);
1150 ASSERT(texelBytes == 2);
1151
1152 if (!ctx->_ImageTransferState &&
1153 !srcPacking->SwapBytes &&
1154 dstFormat == MESA_FORMAT_RGB565 &&
1155 baseInternalFormat == GL_RGB &&
1156 srcFormat == GL_RGB &&
1157 srcType == GL_UNSIGNED_SHORT_5_6_5) {
1158 /* simple memcpy path */
1159 memcpy_texture(ctx, dims,
1160 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1161 dstRowStride,
1162 dstImageOffsets,
1163 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1164 srcAddr, srcPacking);
1165 }
1166 else if (!ctx->_ImageTransferState &&
1167 !srcPacking->SwapBytes &&
1168 baseInternalFormat == GL_RGB &&
1169 srcFormat == GL_RGB &&
1170 srcType == GL_UNSIGNED_BYTE &&
1171 dims == 2) {
1172 /* do optimized tex store */
1173 const GLint srcRowStride =
1174 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1175 const GLubyte *src = (const GLubyte *)
1176 _mesa_image_address(dims, srcPacking, srcAddr, srcWidth, srcHeight,
1177 srcFormat, srcType, 0, 0, 0);
1178 GLubyte *dst = (GLubyte *) dstAddr
1179 + dstYoffset * dstRowStride
1180 + dstXoffset * texelBytes;
1181 GLint row, col;
1182 for (row = 0; row < srcHeight; row++) {
1183 const GLubyte *srcUB = (const GLubyte *) src;
1184 GLushort *dstUS = (GLushort *) dst;
1185 /* check for byteswapped format */
1186 if (dstFormat == MESA_FORMAT_RGB565) {
1187 for (col = 0; col < srcWidth; col++) {
1188 dstUS[col] = PACK_COLOR_565( srcUB[0], srcUB[1], srcUB[2] );
1189 srcUB += 3;
1190 }
1191 }
1192 else {
1193 for (col = 0; col < srcWidth; col++) {
1194 dstUS[col] = PACK_COLOR_565_REV( srcUB[0], srcUB[1], srcUB[2] );
1195 srcUB += 3;
1196 }
1197 }
1198 dst += dstRowStride;
1199 src += srcRowStride;
1200 }
1201 }
1202 else {
1203 /* general path */
1204 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1205 baseInternalFormat,
1206 baseFormat,
1207 srcWidth, srcHeight, srcDepth,
1208 srcFormat, srcType, srcAddr,
1209 srcPacking);
1210 const GLchan *src = tempImage;
1211 GLint img, row, col;
1212 if (!tempImage)
1213 return GL_FALSE;
1214 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1215 for (img = 0; img < srcDepth; img++) {
1216 GLubyte *dstRow = (GLubyte *) dstAddr
1217 + dstImageOffsets[dstZoffset + img] * texelBytes
1218 + dstYoffset * dstRowStride
1219 + dstXoffset * texelBytes;
1220 for (row = 0; row < srcHeight; row++) {
1221 GLushort *dstUS = (GLushort *) dstRow;
1222 /* check for byteswapped format */
1223 if (dstFormat == MESA_FORMAT_RGB565) {
1224 for (col = 0; col < srcWidth; col++) {
1225 dstUS[col] = PACK_COLOR_565( CHAN_TO_UBYTE(src[RCOMP]),
1226 CHAN_TO_UBYTE(src[GCOMP]),
1227 CHAN_TO_UBYTE(src[BCOMP]) );
1228 src += 3;
1229 }
1230 }
1231 else {
1232 for (col = 0; col < srcWidth; col++) {
1233 dstUS[col] = PACK_COLOR_565_REV( CHAN_TO_UBYTE(src[RCOMP]),
1234 CHAN_TO_UBYTE(src[GCOMP]),
1235 CHAN_TO_UBYTE(src[BCOMP]) );
1236 src += 3;
1237 }
1238 }
1239 dstRow += dstRowStride;
1240 }
1241 }
1242 _mesa_free((void *) tempImage);
1243 }
1244 return GL_TRUE;
1245 }
1246
1247
1248 /**
1249 * Store a texture in MESA_FORMAT_RGBA8888 or MESA_FORMAT_RGBA8888_REV.
1250 */
1251 static GLboolean
1252 _mesa_texstore_rgba8888(TEXSTORE_PARAMS)
1253 {
1254 const GLboolean littleEndian = _mesa_little_endian();
1255 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1256 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1257
1258 ASSERT(dstFormat == MESA_FORMAT_RGBA8888 ||
1259 dstFormat == MESA_FORMAT_RGBA8888_REV);
1260 ASSERT(texelBytes == 4);
1261
1262 if (!ctx->_ImageTransferState &&
1263 !srcPacking->SwapBytes &&
1264 dstFormat == MESA_FORMAT_RGBA8888 &&
1265 baseInternalFormat == GL_RGBA &&
1266 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1267 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1268 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1269 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && littleEndian))) {
1270 /* simple memcpy path */
1271 memcpy_texture(ctx, dims,
1272 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1273 dstRowStride,
1274 dstImageOffsets,
1275 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1276 srcAddr, srcPacking);
1277 }
1278 else if (!ctx->_ImageTransferState &&
1279 !srcPacking->SwapBytes &&
1280 dstFormat == MESA_FORMAT_RGBA8888_REV &&
1281 baseInternalFormat == GL_RGBA &&
1282 ((srcFormat == GL_RGBA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) ||
1283 (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1284 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_INT_8_8_8_8) ||
1285 (srcFormat == GL_ABGR_EXT && srcType == GL_UNSIGNED_BYTE && !littleEndian))) {
1286 /* simple memcpy path */
1287 memcpy_texture(ctx, dims,
1288 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1289 dstRowStride,
1290 dstImageOffsets,
1291 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1292 srcAddr, srcPacking);
1293 }
1294 else if (!ctx->_ImageTransferState &&
1295 (srcType == GL_UNSIGNED_BYTE ||
1296 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1297 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1298 can_swizzle(baseInternalFormat) &&
1299 can_swizzle(srcFormat)) {
1300
1301 GLubyte dstmap[4];
1302
1303 /* dstmap - how to swizzle from RGBA to dst format:
1304 */
1305 if ((littleEndian && dstFormat == MESA_FORMAT_RGBA8888) ||
1306 (!littleEndian && dstFormat == MESA_FORMAT_RGBA8888_REV)) {
1307 dstmap[3] = 0;
1308 dstmap[2] = 1;
1309 dstmap[1] = 2;
1310 dstmap[0] = 3;
1311 }
1312 else {
1313 dstmap[3] = 3;
1314 dstmap[2] = 2;
1315 dstmap[1] = 1;
1316 dstmap[0] = 0;
1317 }
1318
1319 _mesa_swizzle_ubyte_image(ctx, dims,
1320 srcFormat,
1321 srcType,
1322 baseInternalFormat,
1323 dstmap, 4,
1324 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1325 dstRowStride, dstImageOffsets,
1326 srcWidth, srcHeight, srcDepth, srcAddr,
1327 srcPacking);
1328 }
1329 else {
1330 /* general path */
1331 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1332 baseInternalFormat,
1333 baseFormat,
1334 srcWidth, srcHeight, srcDepth,
1335 srcFormat, srcType, srcAddr,
1336 srcPacking);
1337 const GLchan *src = tempImage;
1338 GLint img, row, col;
1339 if (!tempImage)
1340 return GL_FALSE;
1341 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1342 for (img = 0; img < srcDepth; img++) {
1343 GLubyte *dstRow = (GLubyte *) dstAddr
1344 + dstImageOffsets[dstZoffset + img] * texelBytes
1345 + dstYoffset * dstRowStride
1346 + dstXoffset * texelBytes;
1347 for (row = 0; row < srcHeight; row++) {
1348 GLuint *dstUI = (GLuint *) dstRow;
1349 if (dstFormat == MESA_FORMAT_RGBA8888) {
1350 for (col = 0; col < srcWidth; col++) {
1351 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[RCOMP]),
1352 CHAN_TO_UBYTE(src[GCOMP]),
1353 CHAN_TO_UBYTE(src[BCOMP]),
1354 CHAN_TO_UBYTE(src[ACOMP]) );
1355 src += 4;
1356 }
1357 }
1358 else {
1359 for (col = 0; col < srcWidth; col++) {
1360 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[RCOMP]),
1361 CHAN_TO_UBYTE(src[GCOMP]),
1362 CHAN_TO_UBYTE(src[BCOMP]),
1363 CHAN_TO_UBYTE(src[ACOMP]) );
1364 src += 4;
1365 }
1366 }
1367 dstRow += dstRowStride;
1368 }
1369 }
1370 _mesa_free((void *) tempImage);
1371 }
1372 return GL_TRUE;
1373 }
1374
1375
1376 static GLboolean
1377 _mesa_texstore_argb8888(TEXSTORE_PARAMS)
1378 {
1379 const GLboolean littleEndian = _mesa_little_endian();
1380 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1381 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1382
1383 ASSERT(dstFormat == MESA_FORMAT_ARGB8888 ||
1384 dstFormat == MESA_FORMAT_ARGB8888_REV ||
1385 dstFormat == MESA_FORMAT_XRGB8888);
1386 ASSERT(texelBytes == 4);
1387
1388 if (!ctx->_ImageTransferState &&
1389 !srcPacking->SwapBytes &&
1390 (dstFormat == MESA_FORMAT_ARGB8888 ||
1391 dstFormat == MESA_FORMAT_XRGB8888) &&
1392 baseInternalFormat == GL_RGBA &&
1393 srcFormat == GL_BGRA &&
1394 ((srcType == GL_UNSIGNED_BYTE && littleEndian) ||
1395 srcType == GL_UNSIGNED_INT_8_8_8_8_REV)) {
1396 /* simple memcpy path (little endian) */
1397 memcpy_texture(ctx, dims,
1398 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1399 dstRowStride,
1400 dstImageOffsets,
1401 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1402 srcAddr, srcPacking);
1403 }
1404 else if (!ctx->_ImageTransferState &&
1405 !srcPacking->SwapBytes &&
1406 dstFormat == MESA_FORMAT_ARGB8888_REV &&
1407 baseInternalFormat == GL_RGBA &&
1408 srcFormat == GL_BGRA &&
1409 ((srcType == GL_UNSIGNED_BYTE && !littleEndian) ||
1410 srcType == GL_UNSIGNED_INT_8_8_8_8)) {
1411 /* simple memcpy path (big endian) */
1412 memcpy_texture(ctx, dims,
1413 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1414 dstRowStride,
1415 dstImageOffsets,
1416 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1417 srcAddr, srcPacking);
1418 }
1419 else if (!ctx->_ImageTransferState &&
1420 !srcPacking->SwapBytes &&
1421 (dstFormat == MESA_FORMAT_ARGB8888 ||
1422 dstFormat == MESA_FORMAT_XRGB8888) &&
1423 srcFormat == GL_RGB &&
1424 (baseInternalFormat == GL_RGBA ||
1425 baseInternalFormat == GL_RGB) &&
1426 srcType == GL_UNSIGNED_BYTE) {
1427 int img, row, col;
1428 for (img = 0; img < srcDepth; img++) {
1429 const GLint srcRowStride =
1430 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1431 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1432 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1433 GLubyte *dstRow = (GLubyte *) dstAddr
1434 + dstImageOffsets[dstZoffset + img] * texelBytes
1435 + dstYoffset * dstRowStride
1436 + dstXoffset * texelBytes;
1437 for (row = 0; row < srcHeight; row++) {
1438 GLuint *d4 = (GLuint *) dstRow;
1439 for (col = 0; col < srcWidth; col++) {
1440 d4[col] = PACK_COLOR_8888(0xff,
1441 srcRow[col * 3 + RCOMP],
1442 srcRow[col * 3 + GCOMP],
1443 srcRow[col * 3 + BCOMP]);
1444 }
1445 dstRow += dstRowStride;
1446 srcRow += srcRowStride;
1447 }
1448 }
1449 }
1450 else if (!ctx->_ImageTransferState &&
1451 !srcPacking->SwapBytes &&
1452 dstFormat == MESA_FORMAT_ARGB8888 &&
1453 srcFormat == GL_RGBA &&
1454 baseInternalFormat == GL_RGBA &&
1455 srcType == GL_UNSIGNED_BYTE) {
1456 /* same as above case, but src data has alpha too */
1457 GLint img, row, col;
1458 /* For some reason, streaming copies to write-combined regions
1459 * are extremely sensitive to the characteristics of how the
1460 * source data is retrieved. By reordering the source reads to
1461 * be in-order, the speed of this operation increases by half.
1462 * Strangely the same isn't required for the RGB path, above.
1463 */
1464 for (img = 0; img < srcDepth; img++) {
1465 const GLint srcRowStride =
1466 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1467 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1468 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1469 GLubyte *dstRow = (GLubyte *) dstAddr
1470 + dstImageOffsets[dstZoffset + img] * texelBytes
1471 + dstYoffset * dstRowStride
1472 + dstXoffset * texelBytes;
1473 for (row = 0; row < srcHeight; row++) {
1474 GLuint *d4 = (GLuint *) dstRow;
1475 for (col = 0; col < srcWidth; col++) {
1476 d4[col] = PACK_COLOR_8888(srcRow[col * 4 + ACOMP],
1477 srcRow[col * 4 + RCOMP],
1478 srcRow[col * 4 + GCOMP],
1479 srcRow[col * 4 + BCOMP]);
1480 }
1481 dstRow += dstRowStride;
1482 srcRow += srcRowStride;
1483 }
1484 }
1485 }
1486 else if (!ctx->_ImageTransferState &&
1487 (srcType == GL_UNSIGNED_BYTE ||
1488 srcType == GL_UNSIGNED_INT_8_8_8_8 ||
1489 srcType == GL_UNSIGNED_INT_8_8_8_8_REV) &&
1490 can_swizzle(baseInternalFormat) &&
1491 can_swizzle(srcFormat)) {
1492
1493 GLubyte dstmap[4];
1494
1495 /* dstmap - how to swizzle from RGBA to dst format:
1496 */
1497 if ((littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1498 (littleEndian && dstFormat == MESA_FORMAT_XRGB8888) ||
1499 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV)) {
1500 dstmap[3] = 3; /* alpha */
1501 dstmap[2] = 0; /* red */
1502 dstmap[1] = 1; /* green */
1503 dstmap[0] = 2; /* blue */
1504 }
1505 else {
1506 assert((littleEndian && dstFormat == MESA_FORMAT_ARGB8888_REV) ||
1507 (!littleEndian && dstFormat == MESA_FORMAT_ARGB8888) ||
1508 (!littleEndian && dstFormat == MESA_FORMAT_XRGB8888));
1509 dstmap[3] = 2;
1510 dstmap[2] = 1;
1511 dstmap[1] = 0;
1512 dstmap[0] = 3;
1513 }
1514
1515 _mesa_swizzle_ubyte_image(ctx, dims,
1516 srcFormat,
1517 srcType,
1518
1519 baseInternalFormat,
1520 dstmap, 4,
1521 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1522 dstRowStride,
1523 dstImageOffsets,
1524 srcWidth, srcHeight, srcDepth, srcAddr,
1525 srcPacking);
1526 }
1527 else {
1528 /* general path */
1529 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1530 baseInternalFormat,
1531 baseFormat,
1532 srcWidth, srcHeight, srcDepth,
1533 srcFormat, srcType, srcAddr,
1534 srcPacking);
1535 const GLchan *src = tempImage;
1536 GLint img, row, col;
1537 if (!tempImage)
1538 return GL_FALSE;
1539 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1540 for (img = 0; img < srcDepth; img++) {
1541 GLubyte *dstRow = (GLubyte *) dstAddr
1542 + dstImageOffsets[dstZoffset + img] * texelBytes
1543 + dstYoffset * dstRowStride
1544 + dstXoffset * texelBytes;
1545 for (row = 0; row < srcHeight; row++) {
1546 GLuint *dstUI = (GLuint *) dstRow;
1547 if (dstFormat == MESA_FORMAT_ARGB8888) {
1548 for (col = 0; col < srcWidth; col++) {
1549 dstUI[col] = PACK_COLOR_8888( CHAN_TO_UBYTE(src[ACOMP]),
1550 CHAN_TO_UBYTE(src[RCOMP]),
1551 CHAN_TO_UBYTE(src[GCOMP]),
1552 CHAN_TO_UBYTE(src[BCOMP]) );
1553 src += 4;
1554 }
1555 }
1556 else if (dstFormat == MESA_FORMAT_XRGB8888) {
1557 for (col = 0; col < srcWidth; col++) {
1558 dstUI[col] = PACK_COLOR_8888( 0xff,
1559 CHAN_TO_UBYTE(src[RCOMP]),
1560 CHAN_TO_UBYTE(src[GCOMP]),
1561 CHAN_TO_UBYTE(src[BCOMP]) );
1562 src += 4;
1563 }
1564 }
1565 else {
1566 for (col = 0; col < srcWidth; col++) {
1567 dstUI[col] = PACK_COLOR_8888_REV( CHAN_TO_UBYTE(src[ACOMP]),
1568 CHAN_TO_UBYTE(src[RCOMP]),
1569 CHAN_TO_UBYTE(src[GCOMP]),
1570 CHAN_TO_UBYTE(src[BCOMP]) );
1571 src += 4;
1572 }
1573 }
1574 dstRow += dstRowStride;
1575 }
1576 }
1577 _mesa_free((void *) tempImage);
1578 }
1579 return GL_TRUE;
1580 }
1581
1582
1583 static GLboolean
1584 _mesa_texstore_rgb888(TEXSTORE_PARAMS)
1585 {
1586 const GLboolean littleEndian = _mesa_little_endian();
1587 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1588 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1589
1590 ASSERT(dstFormat == MESA_FORMAT_RGB888);
1591 ASSERT(texelBytes == 3);
1592
1593 if (!ctx->_ImageTransferState &&
1594 !srcPacking->SwapBytes &&
1595 baseInternalFormat == GL_RGB &&
1596 srcFormat == GL_BGR &&
1597 srcType == GL_UNSIGNED_BYTE &&
1598 littleEndian) {
1599 /* simple memcpy path */
1600 memcpy_texture(ctx, dims,
1601 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1602 dstRowStride,
1603 dstImageOffsets,
1604 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1605 srcAddr, srcPacking);
1606 }
1607 else if (!ctx->_ImageTransferState &&
1608 !srcPacking->SwapBytes &&
1609 srcFormat == GL_RGBA &&
1610 srcType == GL_UNSIGNED_BYTE) {
1611 /* extract RGB from RGBA */
1612 GLint img, row, col;
1613 for (img = 0; img < srcDepth; img++) {
1614 const GLint srcRowStride =
1615 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1616 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1617 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1618 GLubyte *dstRow = (GLubyte *) dstAddr
1619 + dstImageOffsets[dstZoffset + img] * texelBytes
1620 + dstYoffset * dstRowStride
1621 + dstXoffset * texelBytes;
1622 for (row = 0; row < srcHeight; row++) {
1623 for (col = 0; col < srcWidth; col++) {
1624 dstRow[col * 3 + 0] = srcRow[col * 4 + BCOMP];
1625 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1626 dstRow[col * 3 + 2] = srcRow[col * 4 + RCOMP];
1627 }
1628 dstRow += dstRowStride;
1629 srcRow += srcRowStride;
1630 }
1631 }
1632 }
1633 else if (!ctx->_ImageTransferState &&
1634 srcType == GL_UNSIGNED_BYTE &&
1635 can_swizzle(baseInternalFormat) &&
1636 can_swizzle(srcFormat)) {
1637
1638 GLubyte dstmap[4];
1639
1640 /* dstmap - how to swizzle from RGBA to dst format:
1641 */
1642 dstmap[0] = 2;
1643 dstmap[1] = 1;
1644 dstmap[2] = 0;
1645 dstmap[3] = ONE; /* ? */
1646
1647 _mesa_swizzle_ubyte_image(ctx, dims,
1648 srcFormat,
1649 srcType,
1650 baseInternalFormat,
1651 dstmap, 3,
1652 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1653 dstRowStride, dstImageOffsets,
1654 srcWidth, srcHeight, srcDepth, srcAddr,
1655 srcPacking);
1656 }
1657 else {
1658 /* general path */
1659 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1660 baseInternalFormat,
1661 baseFormat,
1662 srcWidth, srcHeight, srcDepth,
1663 srcFormat, srcType, srcAddr,
1664 srcPacking);
1665 const GLchan *src = (const GLchan *) tempImage;
1666 GLint img, row, col;
1667 if (!tempImage)
1668 return GL_FALSE;
1669 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1670 for (img = 0; img < srcDepth; img++) {
1671 GLubyte *dstRow = (GLubyte *) dstAddr
1672 + dstImageOffsets[dstZoffset + img] * texelBytes
1673 + dstYoffset * dstRowStride
1674 + dstXoffset * texelBytes;
1675 for (row = 0; row < srcHeight; row++) {
1676 #if 0
1677 if (littleEndian) {
1678 for (col = 0; col < srcWidth; col++) {
1679 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1680 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1681 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1682 srcUB += 3;
1683 }
1684 }
1685 else {
1686 for (col = 0; col < srcWidth; col++) {
1687 dstRow[col * 3 + 0] = srcUB[BCOMP];
1688 dstRow[col * 3 + 1] = srcUB[GCOMP];
1689 dstRow[col * 3 + 2] = srcUB[RCOMP];
1690 srcUB += 3;
1691 }
1692 }
1693 #else
1694 for (col = 0; col < srcWidth; col++) {
1695 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[BCOMP]);
1696 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1697 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[RCOMP]);
1698 src += 3;
1699 }
1700 #endif
1701 dstRow += dstRowStride;
1702 }
1703 }
1704 _mesa_free((void *) tempImage);
1705 }
1706 return GL_TRUE;
1707 }
1708
1709
1710 static GLboolean
1711 _mesa_texstore_bgr888(TEXSTORE_PARAMS)
1712 {
1713 const GLboolean littleEndian = _mesa_little_endian();
1714 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1715 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1716
1717 ASSERT(dstFormat == MESA_FORMAT_BGR888);
1718 ASSERT(texelBytes == 3);
1719
1720 if (!ctx->_ImageTransferState &&
1721 !srcPacking->SwapBytes &&
1722 baseInternalFormat == GL_RGB &&
1723 srcFormat == GL_RGB &&
1724 srcType == GL_UNSIGNED_BYTE &&
1725 littleEndian) {
1726 /* simple memcpy path */
1727 memcpy_texture(ctx, dims,
1728 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1729 dstRowStride,
1730 dstImageOffsets,
1731 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1732 srcAddr, srcPacking);
1733 }
1734 else if (!ctx->_ImageTransferState &&
1735 !srcPacking->SwapBytes &&
1736 srcFormat == GL_RGBA &&
1737 srcType == GL_UNSIGNED_BYTE) {
1738 /* extract BGR from RGBA */
1739 int img, row, col;
1740 for (img = 0; img < srcDepth; img++) {
1741 const GLint srcRowStride =
1742 _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType);
1743 GLubyte *srcRow = (GLubyte *) _mesa_image_address(dims, srcPacking,
1744 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, 0, 0);
1745 GLubyte *dstRow = (GLubyte *) dstAddr
1746 + dstImageOffsets[dstZoffset + img] * texelBytes
1747 + dstYoffset * dstRowStride
1748 + dstXoffset * texelBytes;
1749 for (row = 0; row < srcHeight; row++) {
1750 for (col = 0; col < srcWidth; col++) {
1751 dstRow[col * 3 + 0] = srcRow[col * 4 + RCOMP];
1752 dstRow[col * 3 + 1] = srcRow[col * 4 + GCOMP];
1753 dstRow[col * 3 + 2] = srcRow[col * 4 + BCOMP];
1754 }
1755 dstRow += dstRowStride;
1756 srcRow += srcRowStride;
1757 }
1758 }
1759 }
1760 else if (!ctx->_ImageTransferState &&
1761 srcType == GL_UNSIGNED_BYTE &&
1762 can_swizzle(baseInternalFormat) &&
1763 can_swizzle(srcFormat)) {
1764
1765 GLubyte dstmap[4];
1766
1767 /* dstmap - how to swizzle from RGBA to dst format:
1768 */
1769 dstmap[0] = 0;
1770 dstmap[1] = 1;
1771 dstmap[2] = 2;
1772 dstmap[3] = ONE; /* ? */
1773
1774 _mesa_swizzle_ubyte_image(ctx, dims,
1775 srcFormat,
1776 srcType,
1777 baseInternalFormat,
1778 dstmap, 3,
1779 dstAddr, dstXoffset, dstYoffset, dstZoffset,
1780 dstRowStride, dstImageOffsets,
1781 srcWidth, srcHeight, srcDepth, srcAddr,
1782 srcPacking);
1783 }
1784 else {
1785 /* general path */
1786 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1787 baseInternalFormat,
1788 baseFormat,
1789 srcWidth, srcHeight, srcDepth,
1790 srcFormat, srcType, srcAddr,
1791 srcPacking);
1792 const GLchan *src = (const GLchan *) tempImage;
1793 GLint img, row, col;
1794 if (!tempImage)
1795 return GL_FALSE;
1796 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1797 for (img = 0; img < srcDepth; img++) {
1798 GLubyte *dstRow = (GLubyte *) dstAddr
1799 + dstImageOffsets[dstZoffset + img] * texelBytes
1800 + dstYoffset * dstRowStride
1801 + dstXoffset * texelBytes;
1802 for (row = 0; row < srcHeight; row++) {
1803 for (col = 0; col < srcWidth; col++) {
1804 dstRow[col * 3 + 0] = CHAN_TO_UBYTE(src[RCOMP]);
1805 dstRow[col * 3 + 1] = CHAN_TO_UBYTE(src[GCOMP]);
1806 dstRow[col * 3 + 2] = CHAN_TO_UBYTE(src[BCOMP]);
1807 src += 3;
1808 }
1809 dstRow += dstRowStride;
1810 }
1811 }
1812 _mesa_free((void *) tempImage);
1813 }
1814 return GL_TRUE;
1815 }
1816
1817
1818 static GLboolean
1819 _mesa_texstore_argb4444(TEXSTORE_PARAMS)
1820 {
1821 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1822 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1823
1824 ASSERT(dstFormat == MESA_FORMAT_ARGB4444 ||
1825 dstFormat == MESA_FORMAT_ARGB4444_REV);
1826 ASSERT(texelBytes == 2);
1827
1828 if (!ctx->_ImageTransferState &&
1829 !srcPacking->SwapBytes &&
1830 dstFormat == MESA_FORMAT_ARGB4444 &&
1831 baseInternalFormat == GL_RGBA &&
1832 srcFormat == GL_BGRA &&
1833 srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV) {
1834 /* simple memcpy path */
1835 memcpy_texture(ctx, dims,
1836 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1837 dstRowStride,
1838 dstImageOffsets,
1839 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1840 srcAddr, srcPacking);
1841 }
1842 else {
1843 /* general path */
1844 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1845 baseInternalFormat,
1846 baseFormat,
1847 srcWidth, srcHeight, srcDepth,
1848 srcFormat, srcType, srcAddr,
1849 srcPacking);
1850 const GLchan *src = tempImage;
1851 GLint img, row, col;
1852 if (!tempImage)
1853 return GL_FALSE;
1854 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1855 for (img = 0; img < srcDepth; img++) {
1856 GLubyte *dstRow = (GLubyte *) dstAddr
1857 + dstImageOffsets[dstZoffset + img] * texelBytes
1858 + dstYoffset * dstRowStride
1859 + dstXoffset * texelBytes;
1860 for (row = 0; row < srcHeight; row++) {
1861 GLushort *dstUS = (GLushort *) dstRow;
1862 if (dstFormat == MESA_FORMAT_ARGB4444) {
1863 for (col = 0; col < srcWidth; col++) {
1864 dstUS[col] = PACK_COLOR_4444( CHAN_TO_UBYTE(src[ACOMP]),
1865 CHAN_TO_UBYTE(src[RCOMP]),
1866 CHAN_TO_UBYTE(src[GCOMP]),
1867 CHAN_TO_UBYTE(src[BCOMP]) );
1868 src += 4;
1869 }
1870 }
1871 else {
1872 for (col = 0; col < srcWidth; col++) {
1873 dstUS[col] = PACK_COLOR_4444_REV( CHAN_TO_UBYTE(src[ACOMP]),
1874 CHAN_TO_UBYTE(src[RCOMP]),
1875 CHAN_TO_UBYTE(src[GCOMP]),
1876 CHAN_TO_UBYTE(src[BCOMP]) );
1877 src += 4;
1878 }
1879 }
1880 dstRow += dstRowStride;
1881 }
1882 }
1883 _mesa_free((void *) tempImage);
1884 }
1885 return GL_TRUE;
1886 }
1887
1888 static GLboolean
1889 _mesa_texstore_rgba5551(TEXSTORE_PARAMS)
1890 {
1891 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1892 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1893
1894 ASSERT(dstFormat == MESA_FORMAT_RGBA5551);
1895 ASSERT(texelBytes == 2);
1896
1897 if (!ctx->_ImageTransferState &&
1898 !srcPacking->SwapBytes &&
1899 dstFormat == MESA_FORMAT_RGBA5551 &&
1900 baseInternalFormat == GL_RGBA &&
1901 srcFormat == GL_RGBA &&
1902 srcType == GL_UNSIGNED_SHORT_5_5_5_1) {
1903 /* simple memcpy path */
1904 memcpy_texture(ctx, dims,
1905 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1906 dstRowStride,
1907 dstImageOffsets,
1908 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1909 srcAddr, srcPacking);
1910 }
1911 else {
1912 /* general path */
1913 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1914 baseInternalFormat,
1915 baseFormat,
1916 srcWidth, srcHeight, srcDepth,
1917 srcFormat, srcType, srcAddr,
1918 srcPacking);
1919 const GLchan *src =tempImage;
1920 GLint img, row, col;
1921 if (!tempImage)
1922 return GL_FALSE;
1923 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1924 for (img = 0; img < srcDepth; img++) {
1925 GLubyte *dstRow = (GLubyte *) dstAddr
1926 + dstImageOffsets[dstZoffset + img] * texelBytes
1927 + dstYoffset * dstRowStride
1928 + dstXoffset * texelBytes;
1929 for (row = 0; row < srcHeight; row++) {
1930 GLushort *dstUS = (GLushort *) dstRow;
1931 for (col = 0; col < srcWidth; col++) {
1932 dstUS[col] = PACK_COLOR_5551( CHAN_TO_UBYTE(src[RCOMP]),
1933 CHAN_TO_UBYTE(src[GCOMP]),
1934 CHAN_TO_UBYTE(src[BCOMP]),
1935 CHAN_TO_UBYTE(src[ACOMP]) );
1936 src += 4;
1937 }
1938 dstRow += dstRowStride;
1939 }
1940 }
1941 _mesa_free((void *) tempImage);
1942 }
1943 return GL_TRUE;
1944 }
1945
1946 static GLboolean
1947 _mesa_texstore_argb1555(TEXSTORE_PARAMS)
1948 {
1949 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
1950 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
1951
1952 ASSERT(dstFormat == MESA_FORMAT_ARGB1555 ||
1953 dstFormat == MESA_FORMAT_ARGB1555_REV);
1954 ASSERT(texelBytes == 2);
1955
1956 if (!ctx->_ImageTransferState &&
1957 !srcPacking->SwapBytes &&
1958 dstFormat == MESA_FORMAT_ARGB1555 &&
1959 baseInternalFormat == GL_RGBA &&
1960 srcFormat == GL_BGRA &&
1961 srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV) {
1962 /* simple memcpy path */
1963 memcpy_texture(ctx, dims,
1964 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
1965 dstRowStride,
1966 dstImageOffsets,
1967 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
1968 srcAddr, srcPacking);
1969 }
1970 else {
1971 /* general path */
1972 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
1973 baseInternalFormat,
1974 baseFormat,
1975 srcWidth, srcHeight, srcDepth,
1976 srcFormat, srcType, srcAddr,
1977 srcPacking);
1978 const GLchan *src =tempImage;
1979 GLint img, row, col;
1980 if (!tempImage)
1981 return GL_FALSE;
1982 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
1983 for (img = 0; img < srcDepth; img++) {
1984 GLubyte *dstRow = (GLubyte *) dstAddr
1985 + dstImageOffsets[dstZoffset + img] * texelBytes
1986 + dstYoffset * dstRowStride
1987 + dstXoffset * texelBytes;
1988 for (row = 0; row < srcHeight; row++) {
1989 GLushort *dstUS = (GLushort *) dstRow;
1990 if (dstFormat == MESA_FORMAT_ARGB1555) {
1991 for (col = 0; col < srcWidth; col++) {
1992 dstUS[col] = PACK_COLOR_1555( CHAN_TO_UBYTE(src[ACOMP]),
1993 CHAN_TO_UBYTE(src[RCOMP]),
1994 CHAN_TO_UBYTE(src[GCOMP]),
1995 CHAN_TO_UBYTE(src[BCOMP]) );
1996 src += 4;
1997 }
1998 }
1999 else {
2000 for (col = 0; col < srcWidth; col++) {
2001 dstUS[col] = PACK_COLOR_1555_REV( CHAN_TO_UBYTE(src[ACOMP]),
2002 CHAN_TO_UBYTE(src[RCOMP]),
2003 CHAN_TO_UBYTE(src[GCOMP]),
2004 CHAN_TO_UBYTE(src[BCOMP]) );
2005 src += 4;
2006 }
2007 }
2008 dstRow += dstRowStride;
2009 }
2010 }
2011 _mesa_free((void *) tempImage);
2012 }
2013 return GL_TRUE;
2014 }
2015
2016
2017 static GLboolean
2018 _mesa_texstore_al88(TEXSTORE_PARAMS)
2019 {
2020 const GLboolean littleEndian = _mesa_little_endian();
2021 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2022 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2023
2024 ASSERT(dstFormat == MESA_FORMAT_AL88 ||
2025 dstFormat == MESA_FORMAT_AL88_REV);
2026 ASSERT(texelBytes == 2);
2027
2028 if (!ctx->_ImageTransferState &&
2029 !srcPacking->SwapBytes &&
2030 dstFormat == MESA_FORMAT_AL88 &&
2031 baseInternalFormat == GL_LUMINANCE_ALPHA &&
2032 srcFormat == GL_LUMINANCE_ALPHA &&
2033 srcType == GL_UNSIGNED_BYTE &&
2034 littleEndian) {
2035 /* simple memcpy path */
2036 memcpy_texture(ctx, dims,
2037 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2038 dstRowStride,
2039 dstImageOffsets,
2040 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2041 srcAddr, srcPacking);
2042 }
2043 else if (!ctx->_ImageTransferState &&
2044 littleEndian &&
2045 srcType == GL_UNSIGNED_BYTE &&
2046 can_swizzle(baseInternalFormat) &&
2047 can_swizzle(srcFormat)) {
2048
2049 GLubyte dstmap[4];
2050
2051 /* dstmap - how to swizzle from RGBA to dst format:
2052 */
2053 if ((littleEndian && dstFormat == MESA_FORMAT_AL88) ||
2054 (!littleEndian && dstFormat == MESA_FORMAT_AL88_REV)) {
2055 dstmap[0] = 0;
2056 dstmap[1] = 3;
2057 }
2058 else {
2059 dstmap[0] = 3;
2060 dstmap[1] = 0;
2061 }
2062 dstmap[2] = ZERO; /* ? */
2063 dstmap[3] = ONE; /* ? */
2064
2065 _mesa_swizzle_ubyte_image(ctx, dims,
2066 srcFormat,
2067 srcType,
2068 baseInternalFormat,
2069 dstmap, 2,
2070 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2071 dstRowStride, dstImageOffsets,
2072 srcWidth, srcHeight, srcDepth, srcAddr,
2073 srcPacking);
2074 }
2075 else {
2076 /* general path */
2077 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2078 baseInternalFormat,
2079 baseFormat,
2080 srcWidth, srcHeight, srcDepth,
2081 srcFormat, srcType, srcAddr,
2082 srcPacking);
2083 const GLchan *src = tempImage;
2084 GLint img, row, col;
2085 if (!tempImage)
2086 return GL_FALSE;
2087 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2088 for (img = 0; img < srcDepth; img++) {
2089 GLubyte *dstRow = (GLubyte *) dstAddr
2090 + dstImageOffsets[dstZoffset + img] * texelBytes
2091 + dstYoffset * dstRowStride
2092 + dstXoffset * texelBytes;
2093 for (row = 0; row < srcHeight; row++) {
2094 GLushort *dstUS = (GLushort *) dstRow;
2095 if (dstFormat == MESA_FORMAT_AL88) {
2096 for (col = 0; col < srcWidth; col++) {
2097 /* src[0] is luminance, src[1] is alpha */
2098 dstUS[col] = PACK_COLOR_88( CHAN_TO_UBYTE(src[1]),
2099 CHAN_TO_UBYTE(src[0]) );
2100 src += 2;
2101 }
2102 }
2103 else {
2104 for (col = 0; col < srcWidth; col++) {
2105 /* src[0] is luminance, src[1] is alpha */
2106 dstUS[col] = PACK_COLOR_88_REV( CHAN_TO_UBYTE(src[1]),
2107 CHAN_TO_UBYTE(src[0]) );
2108 src += 2;
2109 }
2110 }
2111 dstRow += dstRowStride;
2112 }
2113 }
2114 _mesa_free((void *) tempImage);
2115 }
2116 return GL_TRUE;
2117 }
2118
2119
2120 static GLboolean
2121 _mesa_texstore_rgb332(TEXSTORE_PARAMS)
2122 {
2123 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2124 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2125
2126 ASSERT(dstFormat == MESA_FORMAT_RGB332);
2127 ASSERT(texelBytes == 1);
2128
2129 if (!ctx->_ImageTransferState &&
2130 !srcPacking->SwapBytes &&
2131 baseInternalFormat == GL_RGB &&
2132 srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE_3_3_2) {
2133 /* simple memcpy path */
2134 memcpy_texture(ctx, dims,
2135 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2136 dstRowStride,
2137 dstImageOffsets,
2138 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2139 srcAddr, srcPacking);
2140 }
2141 else {
2142 /* general path */
2143 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2144 baseInternalFormat,
2145 baseFormat,
2146 srcWidth, srcHeight, srcDepth,
2147 srcFormat, srcType, srcAddr,
2148 srcPacking);
2149 const GLchan *src = tempImage;
2150 GLint img, row, col;
2151 if (!tempImage)
2152 return GL_FALSE;
2153 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2154 for (img = 0; img < srcDepth; img++) {
2155 GLubyte *dstRow = (GLubyte *) dstAddr
2156 + dstImageOffsets[dstZoffset + img] * texelBytes
2157 + dstYoffset * dstRowStride
2158 + dstXoffset * texelBytes;
2159 for (row = 0; row < srcHeight; row++) {
2160 for (col = 0; col < srcWidth; col++) {
2161 dstRow[col] = PACK_COLOR_332( CHAN_TO_UBYTE(src[RCOMP]),
2162 CHAN_TO_UBYTE(src[GCOMP]),
2163 CHAN_TO_UBYTE(src[BCOMP]) );
2164 src += 3;
2165 }
2166 dstRow += dstRowStride;
2167 }
2168 }
2169 _mesa_free((void *) tempImage);
2170 }
2171 return GL_TRUE;
2172 }
2173
2174
2175 /**
2176 * Texstore for _mesa_texformat_a8, _mesa_texformat_l8, _mesa_texformat_i8.
2177 */
2178 static GLboolean
2179 _mesa_texstore_a8(TEXSTORE_PARAMS)
2180 {
2181 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2182 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2183
2184 ASSERT(dstFormat == MESA_FORMAT_A8 ||
2185 dstFormat == MESA_FORMAT_L8 ||
2186 dstFormat == MESA_FORMAT_I8);
2187 ASSERT(texelBytes == 1);
2188
2189 if (!ctx->_ImageTransferState &&
2190 !srcPacking->SwapBytes &&
2191 baseInternalFormat == srcFormat &&
2192 srcType == GL_UNSIGNED_BYTE) {
2193 /* simple memcpy path */
2194 memcpy_texture(ctx, dims,
2195 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2196 dstRowStride,
2197 dstImageOffsets,
2198 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2199 srcAddr, srcPacking);
2200 }
2201 else if (!ctx->_ImageTransferState &&
2202 srcType == GL_UNSIGNED_BYTE &&
2203 can_swizzle(baseInternalFormat) &&
2204 can_swizzle(srcFormat)) {
2205
2206 GLubyte dstmap[4];
2207
2208 /* dstmap - how to swizzle from RGBA to dst format:
2209 */
2210 if (dstFormat == MESA_FORMAT_A8) {
2211 dstmap[0] = 3;
2212 }
2213 else {
2214 dstmap[0] = 0;
2215 }
2216 dstmap[1] = ZERO; /* ? */
2217 dstmap[2] = ZERO; /* ? */
2218 dstmap[3] = ONE; /* ? */
2219
2220 _mesa_swizzle_ubyte_image(ctx, dims,
2221 srcFormat,
2222 srcType,
2223 baseInternalFormat,
2224 dstmap, 1,
2225 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2226 dstRowStride, dstImageOffsets,
2227 srcWidth, srcHeight, srcDepth, srcAddr,
2228 srcPacking);
2229 }
2230 else {
2231 /* general path */
2232 const GLchan *tempImage = _mesa_make_temp_chan_image(ctx, dims,
2233 baseInternalFormat,
2234 baseFormat,
2235 srcWidth, srcHeight, srcDepth,
2236 srcFormat, srcType, srcAddr,
2237 srcPacking);
2238 const GLchan *src = tempImage;
2239 GLint img, row, col;
2240 if (!tempImage)
2241 return GL_FALSE;
2242 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2243 for (img = 0; img < srcDepth; img++) {
2244 GLubyte *dstRow = (GLubyte *) dstAddr
2245 + dstImageOffsets[dstZoffset + img] * texelBytes
2246 + dstYoffset * dstRowStride
2247 + dstXoffset * texelBytes;
2248 for (row = 0; row < srcHeight; row++) {
2249 for (col = 0; col < srcWidth; col++) {
2250 dstRow[col] = CHAN_TO_UBYTE(src[col]);
2251 }
2252 dstRow += dstRowStride;
2253 src += srcWidth;
2254 }
2255 }
2256 _mesa_free((void *) tempImage);
2257 }
2258 return GL_TRUE;
2259 }
2260
2261
2262
2263 static GLboolean
2264 _mesa_texstore_ci8(TEXSTORE_PARAMS)
2265 {
2266 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2267
2268 (void) dims; (void) baseInternalFormat;
2269 ASSERT(dstFormat == MESA_FORMAT_CI8);
2270 ASSERT(texelBytes == 1);
2271 ASSERT(baseInternalFormat == GL_COLOR_INDEX);
2272
2273 if (!ctx->_ImageTransferState &&
2274 !srcPacking->SwapBytes &&
2275 srcFormat == GL_COLOR_INDEX &&
2276 srcType == GL_UNSIGNED_BYTE) {
2277 /* simple memcpy path */
2278 memcpy_texture(ctx, dims,
2279 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2280 dstRowStride,
2281 dstImageOffsets,
2282 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2283 srcAddr, srcPacking);
2284 }
2285 else {
2286 /* general path */
2287 GLint img, row;
2288 for (img = 0; img < srcDepth; img++) {
2289 GLubyte *dstRow = (GLubyte *) dstAddr
2290 + dstImageOffsets[dstZoffset + img] * texelBytes
2291 + dstYoffset * dstRowStride
2292 + dstXoffset * texelBytes;
2293 for (row = 0; row < srcHeight; row++) {
2294 const GLvoid *src = _mesa_image_address(dims, srcPacking,
2295 srcAddr, srcWidth, srcHeight, srcFormat, srcType, img, row, 0);
2296 _mesa_unpack_index_span(ctx, srcWidth, GL_UNSIGNED_BYTE, dstRow,
2297 srcType, src, srcPacking,
2298 ctx->_ImageTransferState);
2299 dstRow += dstRowStride;
2300 }
2301 }
2302 }
2303 return GL_TRUE;
2304 }
2305
2306
2307 /**
2308 * Texstore for _mesa_texformat_ycbcr or _mesa_texformat_ycbcr_REV.
2309 */
2310 static GLboolean
2311 _mesa_texstore_ycbcr(TEXSTORE_PARAMS)
2312 {
2313 const GLboolean littleEndian = _mesa_little_endian();
2314 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2315
2316 (void) ctx; (void) dims; (void) baseInternalFormat;
2317
2318 ASSERT((dstFormat == MESA_FORMAT_YCBCR) ||
2319 (dstFormat == MESA_FORMAT_YCBCR_REV));
2320 ASSERT(texelBytes == 2);
2321 ASSERT(ctx->Extensions.MESA_ycbcr_texture);
2322 ASSERT(srcFormat == GL_YCBCR_MESA);
2323 ASSERT((srcType == GL_UNSIGNED_SHORT_8_8_MESA) ||
2324 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA));
2325 ASSERT(baseInternalFormat == GL_YCBCR_MESA);
2326
2327 /* always just memcpy since no pixel transfer ops apply */
2328 memcpy_texture(ctx, dims,
2329 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2330 dstRowStride,
2331 dstImageOffsets,
2332 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2333 srcAddr, srcPacking);
2334
2335 /* Check if we need byte swapping */
2336 /* XXX the logic here _might_ be wrong */
2337 if (srcPacking->SwapBytes ^
2338 (srcType == GL_UNSIGNED_SHORT_8_8_REV_MESA) ^
2339 (dstFormat == MESA_FORMAT_YCBCR_REV) ^
2340 !littleEndian) {
2341 GLint img, row;
2342 for (img = 0; img < srcDepth; img++) {
2343 GLubyte *dstRow = (GLubyte *) dstAddr
2344 + dstImageOffsets[dstZoffset + img] * texelBytes
2345 + dstYoffset * dstRowStride
2346 + dstXoffset * texelBytes;
2347 for (row = 0; row < srcHeight; row++) {
2348 _mesa_swap2((GLushort *) dstRow, srcWidth);
2349 dstRow += dstRowStride;
2350 }
2351 }
2352 }
2353 return GL_TRUE;
2354 }
2355
2356 static GLboolean
2357 _mesa_texstore_dudv8(TEXSTORE_PARAMS)
2358 {
2359 const GLboolean littleEndian = _mesa_little_endian();
2360 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2361
2362 ASSERT(dstFormat == MESA_FORMAT_DUDV8);
2363 ASSERT(texelBytes == 2);
2364 ASSERT(ctx->Extensions.ATI_envmap_bumpmap);
2365 ASSERT((srcFormat == GL_DU8DV8_ATI) ||
2366 (srcFormat == GL_DUDV_ATI));
2367 ASSERT(baseInternalFormat == GL_DUDV_ATI);
2368
2369 if (!srcPacking->SwapBytes && srcType == GL_BYTE &&
2370 littleEndian) {
2371 /* simple memcpy path */
2372 memcpy_texture(ctx, dims,
2373 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2374 dstRowStride,
2375 dstImageOffsets,
2376 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2377 srcAddr, srcPacking);
2378 }
2379 else if (srcType == GL_BYTE) {
2380
2381 GLubyte dstmap[4];
2382
2383 /* dstmap - how to swizzle from RGBA to dst format:
2384 */
2385 if (littleEndian) {
2386 dstmap[0] = 0;
2387 dstmap[1] = 3;
2388 }
2389 else {
2390 dstmap[0] = 3;
2391 dstmap[1] = 0;
2392 }
2393 dstmap[2] = ZERO; /* ? */
2394 dstmap[3] = ONE; /* ? */
2395
2396 _mesa_swizzle_ubyte_image(ctx, dims,
2397 GL_LUMINANCE_ALPHA, /* hack */
2398 GL_UNSIGNED_BYTE, /* hack */
2399 GL_LUMINANCE_ALPHA, /* hack */
2400 dstmap, 2,
2401 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2402 dstRowStride, dstImageOffsets,
2403 srcWidth, srcHeight, srcDepth, srcAddr,
2404 srcPacking);
2405 }
2406 else {
2407 /* general path - note this is defined for 2d textures only */
2408 const GLint components = _mesa_components_in_format(baseInternalFormat);
2409 const GLint srcStride = _mesa_image_row_stride(srcPacking, srcWidth,
2410 srcFormat, srcType);
2411 GLbyte *tempImage, *dst, *src;
2412 GLint row;
2413
2414 tempImage = (GLbyte *) _mesa_malloc(srcWidth * srcHeight * srcDepth
2415 * components * sizeof(GLbyte));
2416 if (!tempImage)
2417 return GL_FALSE;
2418
2419 src = (GLbyte *) _mesa_image_address(dims, srcPacking, srcAddr,
2420 srcWidth, srcHeight,
2421 srcFormat, srcType,
2422 0, 0, 0);
2423
2424 dst = tempImage;
2425 for (row = 0; row < srcHeight; row++) {
2426 _mesa_unpack_dudv_span_byte(ctx, srcWidth, baseInternalFormat,
2427 dst, srcFormat, srcType, src,
2428 srcPacking, 0);
2429 dst += srcWidth * components;
2430 src += srcStride;
2431 }
2432
2433 src = tempImage;
2434 dst = (GLbyte *) dstAddr
2435 + dstYoffset * dstRowStride
2436 + dstXoffset * texelBytes;
2437 for (row = 0; row < srcHeight; row++) {
2438 memcpy(dst, src, srcWidth * texelBytes);
2439 dst += dstRowStride;
2440 src += srcWidth * texelBytes;
2441 }
2442 _mesa_free((void *) tempImage);
2443 }
2444 return GL_TRUE;
2445 }
2446
2447 /**
2448 * Store a texture in MESA_FORMAT_SIGNED_RGBA8888 or MESA_FORMAT_SIGNED_RGBA8888_REV
2449 */
2450 static GLboolean
2451 _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS)
2452 {
2453 const GLboolean littleEndian = _mesa_little_endian();
2454 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2455 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2456
2457 ASSERT(dstFormat == MESA_FORMAT_SIGNED_RGBA8888 ||
2458 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV);
2459 ASSERT(texelBytes == 4);
2460
2461 if (!ctx->_ImageTransferState &&
2462 !srcPacking->SwapBytes &&
2463 dstFormat == MESA_FORMAT_SIGNED_RGBA8888 &&
2464 baseInternalFormat == GL_RGBA &&
2465 ((srcFormat == GL_RGBA && srcType == GL_BYTE && !littleEndian) ||
2466 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && littleEndian))) {
2467 /* simple memcpy path */
2468 memcpy_texture(ctx, dims,
2469 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2470 dstRowStride,
2471 dstImageOffsets,
2472 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2473 srcAddr, srcPacking);
2474 }
2475 else if (!ctx->_ImageTransferState &&
2476 !srcPacking->SwapBytes &&
2477 dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV &&
2478 baseInternalFormat == GL_RGBA &&
2479 ((srcFormat == GL_RGBA && srcType == GL_BYTE && littleEndian) ||
2480 (srcFormat == GL_ABGR_EXT && srcType == GL_BYTE && !littleEndian))) {
2481 /* simple memcpy path */
2482 memcpy_texture(ctx, dims,
2483 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2484 dstRowStride,
2485 dstImageOffsets,
2486 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2487 srcAddr, srcPacking);
2488 }
2489 else if (!ctx->_ImageTransferState &&
2490 (srcType == GL_BYTE) &&
2491 can_swizzle(baseInternalFormat) &&
2492 can_swizzle(srcFormat)) {
2493
2494 GLubyte dstmap[4];
2495
2496 /* dstmap - how to swizzle from RGBA to dst format:
2497 */
2498 if ((littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888) ||
2499 (!littleEndian && dstFormat == MESA_FORMAT_SIGNED_RGBA8888_REV)) {
2500 dstmap[3] = 0;
2501 dstmap[2] = 1;
2502 dstmap[1] = 2;
2503 dstmap[0] = 3;
2504 }
2505 else {
2506 dstmap[3] = 3;
2507 dstmap[2] = 2;
2508 dstmap[1] = 1;
2509 dstmap[0] = 0;
2510 }
2511
2512 _mesa_swizzle_ubyte_image(ctx, dims,
2513 srcFormat,
2514 srcType,
2515 baseInternalFormat,
2516 dstmap, 4,
2517 dstAddr, dstXoffset, dstYoffset, dstZoffset,
2518 dstRowStride, dstImageOffsets,
2519 srcWidth, srcHeight, srcDepth, srcAddr,
2520 srcPacking);
2521 }
2522 else {
2523 /* general path */
2524 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2525 baseInternalFormat,
2526 baseFormat,
2527 srcWidth, srcHeight, srcDepth,
2528 srcFormat, srcType, srcAddr,
2529 srcPacking);
2530 const GLfloat *srcRow = tempImage;
2531 GLint img, row, col;
2532 if (!tempImage)
2533 return GL_FALSE;
2534 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2535 for (img = 0; img < srcDepth; img++) {
2536 GLubyte *dstRow = (GLubyte *) dstAddr
2537 + dstImageOffsets[dstZoffset + img] * texelBytes
2538 + dstYoffset * dstRowStride
2539 + dstXoffset * texelBytes;
2540 for (row = 0; row < srcHeight; row++) {
2541 GLuint *dstUI = (GLuint *) dstRow;
2542 if (dstFormat == MESA_FORMAT_SIGNED_RGBA8888) {
2543 for (col = 0; col < srcWidth; col++) {
2544 dstUI[col] = PACK_COLOR_8888( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2545 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2546 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2547 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2548 srcRow += 4;
2549 }
2550 }
2551 else {
2552 for (col = 0; col < srcWidth; col++) {
2553 dstUI[col] = PACK_COLOR_8888_REV( FLOAT_TO_BYTE_TEX(srcRow[RCOMP]),
2554 FLOAT_TO_BYTE_TEX(srcRow[GCOMP]),
2555 FLOAT_TO_BYTE_TEX(srcRow[BCOMP]),
2556 FLOAT_TO_BYTE_TEX(srcRow[ACOMP]) );
2557 srcRow += 4;
2558 }
2559 }
2560 dstRow += dstRowStride;
2561 }
2562 }
2563 _mesa_free((void *) tempImage);
2564 }
2565 return GL_TRUE;
2566 }
2567
2568 /**
2569 * Store a combined depth/stencil texture image.
2570 */
2571 static GLboolean
2572 _mesa_texstore_z24_s8(TEXSTORE_PARAMS)
2573 {
2574 const GLfloat depthScale = (GLfloat) 0xffffff;
2575 const GLint srcRowStride
2576 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2577 / sizeof(GLuint);
2578 GLint img, row;
2579
2580 ASSERT(dstFormat == MESA_FORMAT_Z24_S8);
2581 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2582 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2583
2584 /* In case we only upload depth we need to preserve the stencil */
2585 if (srcFormat == GL_DEPTH_COMPONENT) {
2586 for (img = 0; img < srcDepth; img++) {
2587 GLuint *dstRow = (GLuint *) dstAddr
2588 + dstImageOffsets[dstZoffset + img]
2589 + dstYoffset * dstRowStride / sizeof(GLuint)
2590 + dstXoffset;
2591 const GLuint *src
2592 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2593 srcWidth, srcHeight,
2594 srcFormat, srcType,
2595 img, 0, 0);
2596 for (row = 0; row < srcHeight; row++) {
2597 GLuint depth[MAX_WIDTH];
2598 GLint i;
2599 _mesa_unpack_depth_span(ctx, srcWidth,
2600 GL_UNSIGNED_INT, /* dst type */
2601 depth, /* dst addr */
2602 depthScale,
2603 srcType, src, srcPacking);
2604
2605 for (i = 0; i < srcWidth; i++)
2606 dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF);
2607
2608 src += srcRowStride;
2609 dstRow += dstRowStride / sizeof(GLuint);
2610 }
2611 }
2612 }
2613 else if (ctx->Pixel.DepthScale == 1.0f &&
2614 ctx->Pixel.DepthBias == 0.0f &&
2615 !srcPacking->SwapBytes) {
2616 /* simple path */
2617 memcpy_texture(ctx, dims,
2618 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2619 dstRowStride,
2620 dstImageOffsets,
2621 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2622 srcAddr, srcPacking);
2623 }
2624 else {
2625 /* general path */
2626 const GLint srcRowStride
2627 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2628 / sizeof(GLuint);
2629 GLint img, row;
2630
2631 for (img = 0; img < srcDepth; img++) {
2632 GLuint *dstRow = (GLuint *) dstAddr
2633 + dstImageOffsets[dstZoffset + img]
2634 + dstYoffset * dstRowStride / sizeof(GLuint)
2635 + dstXoffset;
2636 const GLuint *src
2637 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2638 srcWidth, srcHeight,
2639 srcFormat, srcType,
2640 img, 0, 0);
2641 for (row = 0; row < srcHeight; row++) {
2642 GLubyte stencil[MAX_WIDTH];
2643 GLint i;
2644 /* the 24 depth bits will be in the high position: */
2645 _mesa_unpack_depth_span(ctx, srcWidth,
2646 GL_UNSIGNED_INT_24_8_EXT, /* dst type */
2647 dstRow, /* dst addr */
2648 (GLuint) depthScale,
2649 srcType, src, srcPacking);
2650 /* get the 8-bit stencil values */
2651 _mesa_unpack_stencil_span(ctx, srcWidth,
2652 GL_UNSIGNED_BYTE, /* dst type */
2653 stencil, /* dst addr */
2654 srcType, src, srcPacking,
2655 ctx->_ImageTransferState);
2656 /* merge stencil values into depth values */
2657 for (i = 0; i < srcWidth; i++)
2658 dstRow[i] |= stencil[i];
2659
2660 src += srcRowStride;
2661 dstRow += dstRowStride / sizeof(GLuint);
2662 }
2663 }
2664 }
2665 return GL_TRUE;
2666 }
2667
2668
2669 /**
2670 * Store a combined depth/stencil texture image.
2671 */
2672 static GLboolean
2673 _mesa_texstore_s8_z24(TEXSTORE_PARAMS)
2674 {
2675 const GLuint depthScale = 0xffffff;
2676 const GLint srcRowStride
2677 = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType)
2678 / sizeof(GLuint);
2679 GLint img, row;
2680
2681 ASSERT(dstFormat == MESA_FORMAT_S8_Z24);
2682 ASSERT(srcFormat == GL_DEPTH_STENCIL_EXT || srcFormat == GL_DEPTH_COMPONENT);
2683 ASSERT(srcFormat != GL_DEPTH_STENCIL_EXT || srcType == GL_UNSIGNED_INT_24_8_EXT);
2684
2685 /* In case we only upload depth we need to preserve the stencil */
2686 if (srcFormat == GL_DEPTH_COMPONENT) {
2687 for (img = 0; img < srcDepth; img++) {
2688 GLuint *dstRow = (GLuint *) dstAddr
2689 + dstImageOffsets[dstZoffset + img]
2690 + dstYoffset * dstRowStride / sizeof(GLuint)
2691 + dstXoffset;
2692 const GLuint *src
2693 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2694 srcWidth, srcHeight,
2695 srcFormat, srcType,
2696 img, 0, 0);
2697 for (row = 0; row < srcHeight; row++) {
2698 GLuint depth[MAX_WIDTH];
2699 GLint i;
2700 _mesa_unpack_depth_span(ctx, srcWidth,
2701 GL_UNSIGNED_INT, /* dst type */
2702 depth, /* dst addr */
2703 depthScale,
2704 srcType, src, srcPacking);
2705
2706 for (i = 0; i < srcWidth; i++)
2707 dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000);
2708
2709 src += srcRowStride;
2710 dstRow += dstRowStride / sizeof(GLuint);
2711 }
2712 }
2713 }
2714 else {
2715 for (img = 0; img < srcDepth; img++) {
2716 GLuint *dstRow = (GLuint *) dstAddr
2717 + dstImageOffsets[dstZoffset + img]
2718 + dstYoffset * dstRowStride / sizeof(GLuint)
2719 + dstXoffset;
2720 const GLuint *src
2721 = (const GLuint *) _mesa_image_address(dims, srcPacking, srcAddr,
2722 srcWidth, srcHeight,
2723 srcFormat, srcType,
2724 img, 0, 0);
2725 for (row = 0; row < srcHeight; row++) {
2726 GLubyte stencil[MAX_WIDTH];
2727 GLint i;
2728 /* the 24 depth bits will be in the low position: */
2729 _mesa_unpack_depth_span(ctx, srcWidth,
2730 GL_UNSIGNED_INT, /* dst type */
2731 dstRow, /* dst addr */
2732 depthScale,
2733 srcType, src, srcPacking);
2734 /* get the 8-bit stencil values */
2735 _mesa_unpack_stencil_span(ctx, srcWidth,
2736 GL_UNSIGNED_BYTE, /* dst type */
2737 stencil, /* dst addr */
2738 srcType, src, srcPacking,
2739 ctx->_ImageTransferState);
2740 /* merge stencil values into depth values */
2741 for (i = 0; i < srcWidth; i++)
2742 dstRow[i] |= stencil[i] << 24;
2743
2744 src += srcRowStride;
2745 dstRow += dstRowStride / sizeof(GLuint);
2746 }
2747 }
2748 }
2749 return GL_TRUE;
2750 }
2751
2752 /**
2753 * Store an image in any of the formats:
2754 * _mesa_texformat_rgba_float32
2755 * _mesa_texformat_rgb_float32
2756 * _mesa_texformat_alpha_float32
2757 * _mesa_texformat_luminance_float32
2758 * _mesa_texformat_luminance_alpha_float32
2759 * _mesa_texformat_intensity_float32
2760 */
2761 static GLboolean
2762 _mesa_texstore_rgba_float32(TEXSTORE_PARAMS)
2763 {
2764 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2765 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2766 const GLint components = _mesa_components_in_format(baseFormat);
2767
2768 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT32 ||
2769 dstFormat == MESA_FORMAT_RGB_FLOAT32 ||
2770 dstFormat == MESA_FORMAT_ALPHA_FLOAT32 ||
2771 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT32 ||
2772 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32 ||
2773 dstFormat == MESA_FORMAT_INTENSITY_FLOAT32);
2774 ASSERT(baseInternalFormat == GL_RGBA ||
2775 baseInternalFormat == GL_RGB ||
2776 baseInternalFormat == GL_ALPHA ||
2777 baseInternalFormat == GL_LUMINANCE ||
2778 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2779 baseInternalFormat == GL_INTENSITY);
2780 ASSERT(texelBytes == components * sizeof(GLfloat));
2781
2782 if (!ctx->_ImageTransferState &&
2783 !srcPacking->SwapBytes &&
2784 baseInternalFormat == srcFormat &&
2785 srcType == GL_FLOAT) {
2786 /* simple memcpy path */
2787 memcpy_texture(ctx, dims,
2788 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2789 dstRowStride,
2790 dstImageOffsets,
2791 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2792 srcAddr, srcPacking);
2793 }
2794 else {
2795 /* general path */
2796 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2797 baseInternalFormat,
2798 baseFormat,
2799 srcWidth, srcHeight, srcDepth,
2800 srcFormat, srcType, srcAddr,
2801 srcPacking);
2802 const GLfloat *srcRow = tempImage;
2803 GLint bytesPerRow;
2804 GLint img, row;
2805 if (!tempImage)
2806 return GL_FALSE;
2807 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2808 bytesPerRow = srcWidth * components * sizeof(GLfloat);
2809 for (img = 0; img < srcDepth; img++) {
2810 GLubyte *dstRow = (GLubyte *) dstAddr
2811 + dstImageOffsets[dstZoffset + img] * texelBytes
2812 + dstYoffset * dstRowStride
2813 + dstXoffset * texelBytes;
2814 for (row = 0; row < srcHeight; row++) {
2815 _mesa_memcpy(dstRow, srcRow, bytesPerRow);
2816 dstRow += dstRowStride;
2817 srcRow += srcWidth * components;
2818 }
2819 }
2820
2821 _mesa_free((void *) tempImage);
2822 }
2823 return GL_TRUE;
2824 }
2825
2826
2827 /**
2828 * As above, but store 16-bit floats.
2829 */
2830 static GLboolean
2831 _mesa_texstore_rgba_float16(TEXSTORE_PARAMS)
2832 {
2833 const GLuint texelBytes = _mesa_get_format_bytes(dstFormat);
2834 const GLenum baseFormat = _mesa_get_format_base_format(dstFormat);
2835 const GLint components = _mesa_components_in_format(baseFormat);
2836
2837 ASSERT(dstFormat == MESA_FORMAT_RGBA_FLOAT16 ||
2838 dstFormat == MESA_FORMAT_RGB_FLOAT16 ||
2839 dstFormat == MESA_FORMAT_ALPHA_FLOAT16 ||
2840 dstFormat == MESA_FORMAT_LUMINANCE_FLOAT16 ||
2841 dstFormat == MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16 ||
2842 dstFormat == MESA_FORMAT_INTENSITY_FLOAT16);
2843 ASSERT(baseInternalFormat == GL_RGBA ||
2844 baseInternalFormat == GL_RGB ||
2845 baseInternalFormat == GL_ALPHA ||
2846 baseInternalFormat == GL_LUMINANCE ||
2847 baseInternalFormat == GL_LUMINANCE_ALPHA ||
2848 baseInternalFormat == GL_INTENSITY);
2849 ASSERT(texelBytes == components * sizeof(GLhalfARB));
2850
2851 if (!ctx->_ImageTransferState &&
2852 !srcPacking->SwapBytes &&
2853 baseInternalFormat == srcFormat &&
2854 srcType == GL_HALF_FLOAT_ARB) {
2855 /* simple memcpy path */
2856 memcpy_texture(ctx, dims,
2857 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
2858 dstRowStride,
2859 dstImageOffsets,
2860 srcWidth, srcHeight, srcDepth, srcFormat, srcType,
2861 srcAddr, srcPacking);
2862 }
2863 else {
2864 /* general path */
2865 const GLfloat *tempImage = make_temp_float_image(ctx, dims,
2866 baseInternalFormat,
2867 baseFormat,
2868 srcWidth, srcHeight, srcDepth,
2869 srcFormat, srcType, srcAddr,
2870 srcPacking);
2871 const GLfloat *src = tempImage;
2872 GLint img, row;
2873 if (!tempImage)
2874 return GL_FALSE;
2875 _mesa_adjust_image_for_convolution(ctx, dims, &srcWidth, &srcHeight);
2876 for (img = 0; img < srcDepth; img++) {
2877 GLubyte *dstRow = (GLubyte *) dstAddr
2878 + dstImageOffsets[dstZoffset + img] * texelBytes
2879 + dstYoffset * dstRowStride
2880 + dstXoffset * texelBytes;
2881 for (row = 0; row < srcHeight; row++) {
2882 GLhalfARB *dstTexel = (GLhalfARB *) dstRow;
2883 GLint i;
2884 for (i = 0; i < srcWidth * components; i++) {
2885 dstTexel[i] = _mesa_float_to_half(src[i]);
2886 }
2887 dstRow += dstRowStride;
2888 src += srcWidth * components;
2889 }
2890 }
2891
2892 _mesa_free((void *) tempImage);
2893 }
2894 return GL_TRUE;
2895 }
2896
2897
2898 #if FEATURE_EXT_texture_sRGB
2899 static GLboolean
2900 _mesa_texstore_srgb8(TEXSTORE_PARAMS)
2901 {
2902 gl_format newDstFormat;
2903 GLboolean k;
2904
2905 ASSERT(dstFormat == MESA_FORMAT_SRGB8);
2906
2907 /* reuse normal rgb texstore code */
2908 newDstFormat = MESA_FORMAT_RGB888;
2909
2910 k = _mesa_texstore_rgb888(ctx, dims, baseInternalFormat,
2911 newDstFormat, dstAddr,
2912 dstXoffset, dstYoffset, dstZoffset,
2913 dstRowStride, dstImageOffsets,
2914 srcWidth, srcHeight, srcDepth,
2915 srcFormat, srcType,
2916 srcAddr, srcPacking);
2917 return k;
2918 }
2919
2920
2921 static GLboolean
2922 _mesa_texstore_srgba8(TEXSTORE_PARAMS)
2923 {
2924 gl_format newDstFormat;
2925 GLboolean k;
2926
2927 ASSERT(dstFormat == MESA_FORMAT_SRGBA8);
2928
2929 /* reuse normal rgba texstore code */
2930 newDstFormat = MESA_FORMAT_RGBA8888;
2931 k = _mesa_texstore_rgba8888(ctx, dims, baseInternalFormat,
2932 newDstFormat, dstAddr,
2933 dstXoffset, dstYoffset, dstZoffset,
2934 dstRowStride, dstImageOffsets,
2935 srcWidth, srcHeight, srcDepth,
2936 srcFormat, srcType,
2937 srcAddr, srcPacking);
2938 return k;
2939 }
2940
2941
2942 static GLboolean
2943 _mesa_texstore_sargb8(TEXSTORE_PARAMS)
2944 {
2945 gl_format newDstFormat;
2946 GLboolean k;
2947
2948 ASSERT(dstFormat == MESA_FORMAT_SARGB8);
2949
2950 /* reuse normal rgba texstore code */
2951 newDstFormat = MESA_FORMAT_ARGB8888;
2952
2953 k = _mesa_texstore_argb8888(ctx, dims, baseInternalFormat,
2954 newDstFormat, dstAddr,
2955 dstXoffset, dstYoffset, dstZoffset,
2956 dstRowStride, dstImageOffsets,
2957 srcWidth, srcHeight, srcDepth,
2958 srcFormat, srcType,
2959 srcAddr, srcPacking);
2960 return k;
2961 }
2962
2963
2964 static GLboolean
2965 _mesa_texstore_sl8(TEXSTORE_PARAMS)
2966 {
2967 gl_format newDstFormat;
2968 GLboolean k;
2969
2970 ASSERT(dstFormat == MESA_FORMAT_SL8);
2971
2972 newDstFormat = MESA_FORMAT_L8;
2973
2974 /* _mesa_textore_a8 handles luminance8 too */
2975 k = _mesa_texstore_a8(ctx, dims, baseInternalFormat,
2976 newDstFormat, dstAddr,
2977 dstXoffset, dstYoffset, dstZoffset,
2978 dstRowStride, dstImageOffsets,
2979 srcWidth, srcHeight, srcDepth,
2980 srcFormat, srcType,
2981 srcAddr, srcPacking);
2982 return k;
2983 }
2984
2985
2986 static GLboolean
2987 _mesa_texstore_sla8(TEXSTORE_PARAMS)
2988 {
2989 gl_format newDstFormat;
2990 GLboolean k;
2991
2992 ASSERT(dstFormat == MESA_FORMAT_SLA8);
2993
2994 /* reuse normal luminance/alpha texstore code */
2995 newDstFormat = MESA_FORMAT_AL88;
2996
2997 k = _mesa_texstore_al88(ctx, dims, baseInternalFormat,
2998 newDstFormat, dstAddr,
2999 dstXoffset, dstYoffset, dstZoffset,
3000 dstRowStride, dstImageOffsets,
3001 srcWidth, srcHeight, srcDepth,
3002 srcFormat, srcType,
3003 srcAddr, srcPacking);
3004 return k;
3005 }
3006
3007 #endif /* FEATURE_EXT_texture_sRGB */
3008
3009
3010
3011
3012 /**
3013 * Table mapping MESA_FORMAT_8 to _mesa_texstore_*()
3014 * XXX this is somewhat temporary.
3015 */
3016 static struct {
3017 gl_format Name;
3018 StoreTexImageFunc Store;
3019 }
3020 texstore_funcs[MESA_FORMAT_COUNT] =
3021 {
3022 { MESA_FORMAT_NONE, NULL },
3023 { MESA_FORMAT_RGBA8888, _mesa_texstore_rgba8888 },
3024 { MESA_FORMAT_RGBA8888_REV, _mesa_texstore_rgba8888 },
3025 { MESA_FORMAT_ARGB8888, _mesa_texstore_argb8888 },
3026 { MESA_FORMAT_ARGB8888_REV, _mesa_texstore_argb8888 },
3027 { MESA_FORMAT_XRGB8888, _mesa_texstore_argb8888 },
3028 { MESA_FORMAT_RGB888, _mesa_texstore_rgb888 },
3029 { MESA_FORMAT_BGR888, _mesa_texstore_bgr888 },
3030 { MESA_FORMAT_RGB565, _mesa_texstore_rgb565 },
3031 { MESA_FORMAT_RGB565_REV, _mesa_texstore_rgb565 },
3032 { MESA_FORMAT_ARGB4444, _mesa_texstore_argb4444 },
3033 { MESA_FORMAT_ARGB4444_REV, _mesa_texstore_argb4444 },
3034 { MESA_FORMAT_RGBA5551, _mesa_texstore_rgba5551 },
3035 { MESA_FORMAT_ARGB1555, _mesa_texstore_argb1555 },
3036 { MESA_FORMAT_ARGB1555_REV, _mesa_texstore_argb1555 },
3037 { MESA_FORMAT_AL88, _mesa_texstore_al88 },
3038 { MESA_FORMAT_AL88_REV, _mesa_texstore_al88 },
3039 { MESA_FORMAT_RGB332, _mesa_texstore_rgb332 },
3040 { MESA_FORMAT_A8, _mesa_texstore_a8 },
3041 { MESA_FORMAT_L8, _mesa_texstore_a8 },
3042 { MESA_FORMAT_I8, _mesa_texstore_a8 },
3043 { MESA_FORMAT_CI8, _mesa_texstore_ci8 },
3044 { MESA_FORMAT_YCBCR, _mesa_texstore_ycbcr },
3045 { MESA_FORMAT_YCBCR_REV, _mesa_texstore_ycbcr },
3046 { MESA_FORMAT_Z24_S8, _mesa_texstore_z24_s8 },
3047 { MESA_FORMAT_S8_Z24, _mesa_texstore_s8_z24 },
3048 { MESA_FORMAT_Z16, _mesa_texstore_z16 },
3049 { MESA_FORMAT_X8_Z24, _mesa_texstore_x8_z24 },
3050 { MESA_FORMAT_Z32, _mesa_texstore_z32 },
3051 { MESA_FORMAT_S8, NULL/*_mesa_texstore_s8*/ },
3052 { MESA_FORMAT_SRGB8, _mesa_texstore_srgb8 },
3053 { MESA_FORMAT_SRGBA8, _mesa_texstore_srgba8 },
3054 { MESA_FORMAT_SARGB8, _mesa_texstore_sargb8 },
3055 { MESA_FORMAT_SL8, _mesa_texstore_sl8 },
3056 { MESA_FORMAT_SLA8, _mesa_texstore_sla8 },
3057 { MESA_FORMAT_SRGB_DXT1, _mesa_texstore_rgb_dxt1 },
3058 { MESA_FORMAT_SRGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3059 { MESA_FORMAT_SRGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3060 { MESA_FORMAT_SRGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3061 { MESA_FORMAT_RGB_FXT1, _mesa_texstore_rgb_fxt1 },
3062 { MESA_FORMAT_RGBA_FXT1, _mesa_texstore_rgba_fxt1 },
3063 { MESA_FORMAT_RGB_DXT1, _mesa_texstore_rgb_dxt1 },
3064 { MESA_FORMAT_RGBA_DXT1, _mesa_texstore_rgba_dxt1 },
3065 { MESA_FORMAT_RGBA_DXT3, _mesa_texstore_rgba_dxt3 },
3066 { MESA_FORMAT_RGBA_DXT5, _mesa_texstore_rgba_dxt5 },
3067 { MESA_FORMAT_RGBA_FLOAT32, _mesa_texstore_rgba_float32 },
3068 { MESA_FORMAT_RGBA_FLOAT16, _mesa_texstore_rgba_float16 },
3069 { MESA_FORMAT_RGB_FLOAT32, _mesa_texstore_rgba_float32 },
3070 { MESA_FORMAT_RGB_FLOAT16, _mesa_texstore_rgba_float16 },
3071 { MESA_FORMAT_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3072 { MESA_FORMAT_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3073 { MESA_FORMAT_LUMINANCE_FLOAT32, _mesa_texstore_rgba_float32 },
3074 { MESA_FORMAT_LUMINANCE_FLOAT16, _mesa_texstore_rgba_float16 },
3075 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32, _mesa_texstore_rgba_float32 },
3076 { MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16, _mesa_texstore_rgba_float16 },
3077 { MESA_FORMAT_INTENSITY_FLOAT32, _mesa_texstore_rgba_float32 },
3078 { MESA_FORMAT_INTENSITY_FLOAT16, _mesa_texstore_rgba_float16 },
3079 { MESA_FORMAT_DUDV8, _mesa_texstore_dudv8 },
3080 { MESA_FORMAT_SIGNED_RGBA8888, _mesa_texstore_signed_rgba8888 },
3081 { MESA_FORMAT_SIGNED_RGBA8888_REV, _mesa_texstore_signed_rgba8888 },
3082 { MESA_FORMAT_SIGNED_RGBA_16, NULL },
3083 };
3084
3085
3086 /**
3087 * Return the StoreTexImageFunc pointer to store an image in the given format.
3088 */
3089 static StoreTexImageFunc
3090 _mesa_get_texstore_func(gl_format format)
3091 {
3092 GLuint i;
3093 #ifdef DEBUG
3094 for (i = 0; i < MESA_FORMAT_COUNT; i++) {
3095 ASSERT(texstore_funcs[i].Name == i);
3096 }
3097 #endif
3098 ASSERT(texstore_funcs[format].Name == format);
3099 return texstore_funcs[format].Store;
3100 }
3101
3102
3103 /**
3104 * Store user data into texture memory.
3105 * Called via glTex[Sub]Image1/2/3D()
3106 */
3107 GLboolean
3108 _mesa_texstore(TEXSTORE_PARAMS)
3109 {
3110 StoreTexImageFunc storeImage;
3111 GLboolean success;
3112
3113 storeImage = _mesa_get_texstore_func(dstFormat);
3114
3115 assert(storeImage);
3116
3117 success = storeImage(ctx, dims, baseInternalFormat,
3118 dstFormat, dstAddr, dstXoffset, dstYoffset, dstZoffset,
3119 dstRowStride, dstImageOffsets,
3120 srcWidth, srcHeight, srcDepth,
3121 srcFormat, srcType, srcAddr, srcPacking);
3122 return success;
3123 }
3124
3125
3126 /**
3127 * Check if an unpack PBO is active prior to fetching a texture image.
3128 * If so, do bounds checking and map the buffer into main memory.
3129 * Any errors detected will be recorded.
3130 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3131 */
3132 const GLvoid *
3133 _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
3134 GLsizei width, GLsizei height, GLsizei depth,
3135 GLenum format, GLenum type, const GLvoid *pixels,
3136 const struct gl_pixelstore_attrib *unpack,
3137 const char *funcName)
3138 {
3139 GLubyte *buf;
3140
3141 if (!_mesa_is_bufferobj(unpack->BufferObj)) {
3142 /* no PBO */
3143 return pixels;
3144 }
3145 if (!_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
3146 format, type, pixels)) {
3147 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3148 return NULL;
3149 }
3150
3151 buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3152 GL_READ_ONLY_ARB, unpack->BufferObj);
3153 if (!buf) {
3154 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3155 return NULL;
3156 }
3157
3158 return ADD_POINTERS(buf, pixels);
3159 }
3160
3161
3162 /**
3163 * Check if an unpack PBO is active prior to fetching a compressed texture
3164 * image.
3165 * If so, do bounds checking and map the buffer into main memory.
3166 * Any errors detected will be recorded.
3167 * The caller _must_ call _mesa_unmap_teximage_pbo() too!
3168 */
3169 const GLvoid *
3170 _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
3171 GLsizei imageSize, const GLvoid *pixels,
3172 const struct gl_pixelstore_attrib *packing,
3173 const char *funcName)
3174 {
3175 GLubyte *buf;
3176
3177 if (!_mesa_is_bufferobj(packing->BufferObj)) {
3178 /* not using a PBO - return pointer unchanged */
3179 return pixels;
3180 }
3181 if ((const GLubyte *) pixels + imageSize >
3182 ((const GLubyte *) 0) + packing->BufferObj->Size) {
3183 /* out of bounds read! */
3184 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(invalid PBO access");
3185 return NULL;
3186 }
3187
3188 buf = (GLubyte*) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3189 GL_READ_ONLY_ARB, packing->BufferObj);
3190 if (!buf) {
3191 _mesa_error(ctx, GL_INVALID_OPERATION, funcName, "(PBO is mapped");
3192 return NULL;
3193 }
3194
3195 return ADD_POINTERS(buf, pixels);
3196 }
3197
3198
3199 /**
3200 * This function must be called after either of the validate_pbo_*_teximage()
3201 * functions. It unmaps the PBO buffer if it was mapped earlier.
3202 */
3203 void
3204 _mesa_unmap_teximage_pbo(GLcontext *ctx,
3205 const struct gl_pixelstore_attrib *unpack)
3206 {
3207 if (_mesa_is_bufferobj(unpack->BufferObj)) {
3208 ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
3209 unpack->BufferObj);
3210 }
3211 }
3212
3213
3214 /** Return texture size in bytes */
3215 static GLuint
3216 texture_size(const struct gl_texture_image *texImage)
3217 {
3218 GLuint sz = _mesa_format_image_size(texImage->TexFormat, texImage->Width,
3219 texImage->Height, texImage->Depth);
3220 return sz;
3221 }
3222
3223
3224 /** Return row stride in bytes */
3225 static GLuint
3226 texture_row_stride(const struct gl_texture_image *texImage)
3227 {
3228 GLuint stride = _mesa_format_row_stride(texImage->TexFormat,
3229 texImage->Width);
3230 return stride;
3231 }
3232
3233
3234
3235 /**
3236 * This is the software fallback for Driver.TexImage1D()
3237 * and Driver.CopyTexImage1D().
3238 * \sa _mesa_store_teximage2d()
3239 * Note that the width may not be the actual texture width since it may
3240 * be changed by convolution w/ GL_REDUCE. The texImage->Width field will
3241 * have the actual texture size.
3242 */
3243 void
3244 _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3245 GLint internalFormat,
3246 GLint width, GLint border,
3247 GLenum format, GLenum type, const GLvoid *pixels,
3248 const struct gl_pixelstore_attrib *packing,
3249 struct gl_texture_object *texObj,
3250 struct gl_texture_image *texImage)
3251 {
3252 GLuint sizeInBytes;
3253 (void) border;
3254
3255 /* allocate memory */
3256 sizeInBytes = texture_size(texImage);
3257 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3258 if (!texImage->Data) {
3259 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3260 return;
3261 }
3262
3263 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3264 pixels, packing, "glTexImage1D");
3265 if (!pixels) {
3266 /* Note: we check for a NULL image pointer here, _after_ we allocated
3267 * memory for the texture. That's what the GL spec calls for.
3268 */
3269 return;
3270 }
3271 else {
3272 const GLint dstRowStride = 0;
3273 GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
3274 texImage->TexFormat,
3275 texImage->Data,
3276 0, 0, 0, /* dstX/Y/Zoffset */
3277 dstRowStride,
3278 texImage->ImageOffsets,
3279 width, 1, 1,
3280 format, type, pixels, packing);
3281 if (!success) {
3282 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
3283 }
3284 }
3285
3286 _mesa_unmap_teximage_pbo(ctx, packing);
3287 }
3288
3289
3290 /**
3291 * This is the software fallback for Driver.TexImage2D()
3292 * and Driver.CopyTexImage2D().
3293 *
3294 * This function is oriented toward storing images in main memory, rather
3295 * than VRAM. Device driver's can easily plug in their own replacement.
3296 *
3297 * Note: width and height may be pre-convolved dimensions, but
3298 * texImage->Width and texImage->Height will be post-convolved dimensions.
3299 */
3300 void
3301 _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3302 GLint internalFormat,
3303 GLint width, GLint height, GLint border,
3304 GLenum format, GLenum type, const void *pixels,
3305 const struct gl_pixelstore_attrib *packing,
3306 struct gl_texture_object *texObj,
3307 struct gl_texture_image *texImage)
3308 {
3309 GLuint sizeInBytes;
3310 (void) border;
3311
3312 /* allocate memory */
3313 sizeInBytes = texture_size(texImage);
3314 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3315 if (!texImage->Data) {
3316 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3317 return;
3318 }
3319
3320 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3321 pixels, packing, "glTexImage2D");
3322 if (!pixels) {
3323 /* Note: we check for a NULL image pointer here, _after_ we allocated
3324 * memory for the texture. That's what the GL spec calls for.
3325 */
3326 return;
3327 }
3328 else {
3329 GLint dstRowStride = texture_row_stride(texImage);
3330 GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
3331 texImage->TexFormat,
3332 texImage->Data,
3333 0, 0, 0, /* dstX/Y/Zoffset */
3334 dstRowStride,
3335 texImage->ImageOffsets,
3336 width, height, 1,
3337 format, type, pixels, packing);
3338 if (!success) {
3339 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
3340 }
3341 }
3342
3343 _mesa_unmap_teximage_pbo(ctx, packing);
3344 }
3345
3346
3347
3348 /**
3349 * This is the software fallback for Driver.TexImage3D()
3350 * and Driver.CopyTexImage3D().
3351 * \sa _mesa_store_teximage2d()
3352 */
3353 void
3354 _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3355 GLint internalFormat,
3356 GLint width, GLint height, GLint depth, GLint border,
3357 GLenum format, GLenum type, const void *pixels,
3358 const struct gl_pixelstore_attrib *packing,
3359 struct gl_texture_object *texObj,
3360 struct gl_texture_image *texImage)
3361 {
3362 GLuint sizeInBytes;
3363 (void) border;
3364
3365 /* allocate memory */
3366 sizeInBytes = texture_size(texImage);
3367 texImage->Data = _mesa_alloc_texmemory(sizeInBytes);
3368 if (!texImage->Data) {
3369 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3370 return;
3371 }
3372
3373 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3374 type, pixels, packing, "glTexImage3D");
3375 if (!pixels) {
3376 /* Note: we check for a NULL image pointer here, _after_ we allocated
3377 * memory for the texture. That's what the GL spec calls for.
3378 */
3379 return;
3380 }
3381 else {
3382 GLint dstRowStride = texture_row_stride(texImage);
3383 GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
3384 texImage->TexFormat,
3385 texImage->Data,
3386 0, 0, 0, /* dstX/Y/Zoffset */
3387 dstRowStride,
3388 texImage->ImageOffsets,
3389 width, height, depth,
3390 format, type, pixels, packing);
3391 if (!success) {
3392 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
3393 }
3394 }
3395
3396 _mesa_unmap_teximage_pbo(ctx, packing);
3397 }
3398
3399
3400
3401
3402 /*
3403 * This is the software fallback for Driver.TexSubImage1D()
3404 * and Driver.CopyTexSubImage1D().
3405 */
3406 void
3407 _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
3408 GLint xoffset, GLint width,
3409 GLenum format, GLenum type, const void *pixels,
3410 const struct gl_pixelstore_attrib *packing,
3411 struct gl_texture_object *texObj,
3412 struct gl_texture_image *texImage)
3413 {
3414 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3415 pixels = _mesa_validate_pbo_teximage(ctx, 1, width, 1, 1, format, type,
3416 pixels, packing, "glTexSubImage1D");
3417 if (!pixels)
3418 return;
3419
3420 {
3421 const GLint dstRowStride = 0;
3422 GLboolean success = _mesa_texstore(ctx, 1, texImage->_BaseFormat,
3423 texImage->TexFormat,
3424 texImage->Data,
3425 xoffset, 0, 0, /* offsets */
3426 dstRowStride,
3427 texImage->ImageOffsets,
3428 width, 1, 1,
3429 format, type, pixels, packing);
3430 if (!success) {
3431 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D");
3432 }
3433 }
3434
3435 _mesa_unmap_teximage_pbo(ctx, packing);
3436 }
3437
3438
3439
3440 /**
3441 * This is the software fallback for Driver.TexSubImage2D()
3442 * and Driver.CopyTexSubImage2D().
3443 */
3444 void
3445 _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
3446 GLint xoffset, GLint yoffset,
3447 GLint width, GLint height,
3448 GLenum format, GLenum type, const void *pixels,
3449 const struct gl_pixelstore_attrib *packing,
3450 struct gl_texture_object *texObj,
3451 struct gl_texture_image *texImage)
3452 {
3453 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3454 pixels = _mesa_validate_pbo_teximage(ctx, 2, width, height, 1, format, type,
3455 pixels, packing, "glTexSubImage2D");
3456 if (!pixels)
3457 return;
3458
3459 {
3460 GLint dstRowStride = texture_row_stride(texImage);
3461 GLboolean success = _mesa_texstore(ctx, 2, texImage->_BaseFormat,
3462 texImage->TexFormat,
3463 texImage->Data,
3464 xoffset, yoffset, 0,
3465 dstRowStride,
3466 texImage->ImageOffsets,
3467 width, height, 1,
3468 format, type, pixels, packing);
3469 if (!success) {
3470 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D");
3471 }
3472 }
3473
3474 _mesa_unmap_teximage_pbo(ctx, packing);
3475 }
3476
3477
3478 /*
3479 * This is the software fallback for Driver.TexSubImage3D().
3480 * and Driver.CopyTexSubImage3D().
3481 */
3482 void
3483 _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
3484 GLint xoffset, GLint yoffset, GLint zoffset,
3485 GLint width, GLint height, GLint depth,
3486 GLenum format, GLenum type, const void *pixels,
3487 const struct gl_pixelstore_attrib *packing,
3488 struct gl_texture_object *texObj,
3489 struct gl_texture_image *texImage)
3490 {
3491 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3492 pixels = _mesa_validate_pbo_teximage(ctx, 3, width, height, depth, format,
3493 type, pixels, packing,
3494 "glTexSubImage3D");
3495 if (!pixels)
3496 return;
3497
3498 {
3499 GLint dstRowStride = texture_row_stride(texImage);
3500 GLboolean success = _mesa_texstore(ctx, 3, texImage->_BaseFormat,
3501 texImage->TexFormat,
3502 texImage->Data,
3503 xoffset, yoffset, zoffset,
3504 dstRowStride,
3505 texImage->ImageOffsets,
3506 width, height, depth,
3507 format, type, pixels, packing);
3508 if (!success) {
3509 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage3D");
3510 }
3511 }
3512
3513 _mesa_unmap_teximage_pbo(ctx, packing);
3514 }
3515
3516
3517 /*
3518 * Fallback for Driver.CompressedTexImage1D()
3519 */
3520 void
3521 _mesa_store_compressed_teximage1d(GLcontext *ctx, GLenum target, GLint level,
3522 GLint internalFormat,
3523 GLint width, GLint border,
3524 GLsizei imageSize, const GLvoid *data,
3525 struct gl_texture_object *texObj,
3526 struct gl_texture_image *texImage)
3527 {
3528 /* this space intentionally left blank */
3529 (void) ctx;
3530 (void) target; (void) level;
3531 (void) internalFormat;
3532 (void) width; (void) border;
3533 (void) imageSize; (void) data;
3534 (void) texObj;
3535 (void) texImage;
3536 }
3537
3538
3539
3540 /**
3541 * Fallback for Driver.CompressedTexImage2D()
3542 */
3543 void
3544 _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
3545 GLint internalFormat,
3546 GLint width, GLint height, GLint border,
3547 GLsizei imageSize, const GLvoid *data,
3548 struct gl_texture_object *texObj,
3549 struct gl_texture_image *texImage)
3550 {
3551 (void) width; (void) height; (void) border;
3552
3553 /* This is pretty simple, basically just do a memcpy without worrying
3554 * about the usual image unpacking or image transfer operations.
3555 */
3556 ASSERT(texObj);
3557 ASSERT(texImage);
3558 ASSERT(texImage->Width > 0);
3559 ASSERT(texImage->Height > 0);
3560 ASSERT(texImage->Depth == 1);
3561 ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
3562
3563 /* allocate storage */
3564 texImage->Data = _mesa_alloc_texmemory(imageSize);
3565 if (!texImage->Data) {
3566 _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2DARB");
3567 return;
3568 }
3569
3570 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3571 &ctx->Unpack,
3572 "glCompressedTexImage2D");
3573 if (!data)
3574 return;
3575
3576 /* copy the data */
3577 MEMCPY(texImage->Data, data, imageSize);
3578
3579 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3580 }
3581
3582
3583
3584 /*
3585 * Fallback for Driver.CompressedTexImage3D()
3586 */
3587 void
3588 _mesa_store_compressed_teximage3d(GLcontext *ctx, GLenum target, GLint level,
3589 GLint internalFormat,
3590 GLint width, GLint height, GLint depth,
3591 GLint border,
3592 GLsizei imageSize, const GLvoid *data,
3593 struct gl_texture_object *texObj,
3594 struct gl_texture_image *texImage)
3595 {
3596 /* this space intentionally left blank */
3597 (void) ctx;
3598 (void) target; (void) level;
3599 (void) internalFormat;
3600 (void) width; (void) height; (void) depth;
3601 (void) border;
3602 (void) imageSize; (void) data;
3603 (void) texObj;
3604 (void) texImage;
3605 }
3606
3607
3608
3609 /**
3610 * Fallback for Driver.CompressedTexSubImage1D()
3611 */
3612 void
3613 _mesa_store_compressed_texsubimage1d(GLcontext *ctx, GLenum target,
3614 GLint level,
3615 GLint xoffset, GLsizei width,
3616 GLenum format,
3617 GLsizei imageSize, const GLvoid *data,
3618 struct gl_texture_object *texObj,
3619 struct gl_texture_image *texImage)
3620 {
3621 /* there are no compressed 1D texture formats yet */
3622 (void) ctx;
3623 (void) target; (void) level;
3624 (void) xoffset; (void) width;
3625 (void) format;
3626 (void) imageSize; (void) data;
3627 (void) texObj;
3628 (void) texImage;
3629 }
3630
3631
3632 /**
3633 * Fallback for Driver.CompressedTexSubImage2D()
3634 */
3635 void
3636 _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
3637 GLint level,
3638 GLint xoffset, GLint yoffset,
3639 GLsizei width, GLsizei height,
3640 GLenum format,
3641 GLsizei imageSize, const GLvoid *data,
3642 struct gl_texture_object *texObj,
3643 struct gl_texture_image *texImage)
3644 {
3645 GLint bytesPerRow, destRowStride, srcRowStride;
3646 GLint i, rows;
3647 GLubyte *dest;
3648 const GLubyte *src;
3649 const gl_format texFormat = texImage->TexFormat;
3650 const GLint destWidth = texImage->Width;
3651 GLuint bw, bh;
3652
3653 _mesa_get_format_block_size(texFormat, &bw, &bh);
3654
3655 (void) level;
3656 (void) format;
3657
3658 /* these should have been caught sooner */
3659 ASSERT((width % bw) == 0 || width == 2 || width == 1);
3660 ASSERT((height % bh) == 0 || height == 2 || height == 1);
3661 ASSERT((xoffset % bw) == 0);
3662 ASSERT((yoffset % bh) == 0);
3663
3664 /* get pointer to src pixels (may be in a pbo which we'll map here) */
3665 data = _mesa_validate_pbo_compressed_teximage(ctx, imageSize, data,
3666 &ctx->Unpack,
3667 "glCompressedTexSubImage2D");
3668 if (!data)
3669 return;
3670
3671 srcRowStride = _mesa_format_row_stride(texFormat, width);
3672 src = (const GLubyte *) data;
3673
3674 destRowStride = _mesa_format_row_stride(texFormat, destWidth);
3675 dest = _mesa_compressed_image_address(xoffset, yoffset, 0,
3676 texFormat, destWidth,
3677 (GLubyte *) texImage->Data);
3678
3679 bytesPerRow = srcRowStride; /* bytes per row of blocks */
3680 rows = height / bh; /* rows in blocks */
3681
3682 /* copy rows of blocks */
3683 for (i = 0; i < rows; i++) {
3684 MEMCPY(dest, src, bytesPerRow);
3685 dest += destRowStride;
3686 src += srcRowStride;
3687 }
3688
3689 _mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
3690 }
3691
3692
3693 /**
3694 * Fallback for Driver.CompressedTexSubImage3D()
3695 */
3696 void
3697 _mesa_store_compressed_texsubimage3d(GLcontext *ctx, GLenum target,
3698 GLint level,
3699 GLint xoffset, GLint yoffset, GLint zoffset,
3700 GLsizei width, GLsizei height, GLsizei depth,
3701 GLenum format,
3702 GLsizei imageSize, const GLvoid *data,
3703 struct gl_texture_object *texObj,
3704 struct gl_texture_image *texImage)
3705 {
3706 /* there are no compressed 3D texture formats yet */
3707 (void) ctx;
3708 (void) target; (void) level;
3709 (void) xoffset; (void) yoffset; (void) zoffset;
3710 (void) width; (void) height; (void) depth;
3711 (void) format;
3712 (void) imageSize; (void) data;
3713 (void) texObj;
3714 (void) texImage;
3715 }