1 /* $Id: texutil.c,v 1.30 2002/06/12 00:53:24 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2002 Brian Paul All Rights Reserved.
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
23 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 * Gareth Hughes <gareth@valinux.com>
40 #include "texformat.h"
44 #define DEBUG_TEXUTIL 0
47 #ifdef MESA_BIG_ENDIAN
48 #define APPEND16( a, b ) ( (a) << 16 | (b) )
50 #define APPEND16( a, b ) ( (a) | (b) << 16 )
54 struct gl_texture_convert
{
55 GLint xoffset
, yoffset
, zoffset
; /* Subimage offset */
56 GLint width
, height
, depth
; /* Subimage region */
58 GLint dstImageWidth
, dstImageHeight
; /* Dest image size */
59 /* Needed for subimage replacement */
60 GLenum format
, type
; /* Source (user) format and type */
62 const struct gl_pixelstore_attrib
*unpacking
;
64 const GLvoid
*srcImage
;
70 typedef GLboolean (*convert_func
)( struct gl_texture_convert
*convert
);
72 #define CONVERT_STRIDE_BIT 0x1
73 #define CONVERT_UNPACKING_BIT 0x2
77 /* =============================================================
81 #define DST_TYPE GLuint
82 #define DST_TEXELS_PER_DWORD 1
84 #define CONVERT_TEXEL( dst, src ) \
85 dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
87 #define CONVERT_DIRECT
89 #define SRC_TEXEL_BYTES 4
91 #define TAG(x) x##_rgba8888_direct
92 #define PRESERVE_DST_TYPE
93 #include "texutil_tmp.h"
96 #define CONVERT_TEXEL( dst, src ) \
97 dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], src[3] )
99 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
101 #define SRC_TEXEL_BYTES 4
103 #define TAG(x) x##_abgr8888_to_rgba8888
104 #define PRESERVE_DST_TYPE
105 #include "texutil_tmp.h"
108 #define CONVERT_TEXEL( dst, src ) \
109 dst = PACK_COLOR_8888_LE( src[0], src[1], src[2], 0xff )
111 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
113 #define SRC_TEXEL_BYTES 3
115 #define TAG(x) x##_bgr888_to_rgba8888
116 #include "texutil_tmp.h"
119 #define CONVERT_RGBA8888( name ) \
121 convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
124 GLint index = convert->index; \
126 if ( convert->format == GL_ABGR_EXT && \
127 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
129 tab = name##_tab_rgba8888_direct; \
131 else if ( convert->format == GL_RGBA && \
132 ( convert->type == GL_UNSIGNED_BYTE || \
133 convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
135 tab = name##_tab_abgr8888_to_rgba8888; \
137 else if ( convert->format == GL_RGB && \
138 convert->type == GL_UNSIGNED_BYTE ) \
140 tab = name##_tab_bgr888_to_rgba8888; \
144 /* Can't handle this source format/type combination */ \
148 return tab[index]( convert ); \
151 CONVERT_RGBA8888( texsubimage2d
)
152 CONVERT_RGBA8888( texsubimage3d
)
156 /* =============================================================
160 #define DST_TYPE GLuint
161 #define DST_TEXELS_PER_DWORD 1
163 #define CONVERT_TEXEL( dst, src ) \
164 dst = PACK_COLOR_8888_LE( src[3], src[2], src[1], src[0] )
166 #define CONVERT_DIRECT
168 #define SRC_TEXEL_BYTES 4
170 #define TAG(x) x##_argb8888_direct
171 #define PRESERVE_DST_TYPE
172 #include "texutil_tmp.h"
175 #define CONVERT_TEXEL( dst, src ) \
176 dst = PACK_COLOR_8888_LE( src[3], src[0], src[1], src[2] )
178 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
180 #define SRC_TEXEL_BYTES 4
182 #define TAG(x) x##_abgr8888_to_argb8888
183 #define PRESERVE_DST_TYPE
184 #include "texutil_tmp.h"
187 #define CONVERT_TEXEL( dst, src ) \
188 dst = PACK_COLOR_8888_LE( 0xff, src[0], src[1], src[2] )
190 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
192 #define SRC_TEXEL_BYTES 3
194 #define TAG(x) x##_bgr888_to_argb8888
195 #include "texutil_tmp.h"
198 #define CONVERT_ARGB8888( name ) \
200 convert_##name##_argb8888( struct gl_texture_convert *convert ) \
203 GLint index = convert->index; \
205 if ( convert->format == GL_BGRA && \
206 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
208 tab = name##_tab_argb8888_direct; \
210 else if ( convert->format == GL_RGBA && \
211 convert->type == GL_UNSIGNED_BYTE ) \
213 tab = name##_tab_abgr8888_to_argb8888; \
215 else if ( convert->format == GL_RGB && \
216 convert->type == GL_UNSIGNED_BYTE ) \
218 tab = name##_tab_bgr888_to_argb8888; \
222 /* Can't handle this source format/type combination */ \
226 return tab[index]( convert ); \
229 CONVERT_ARGB8888( texsubimage2d
)
230 CONVERT_ARGB8888( texsubimage3d
)
234 /* =============================================================
239 convert_texsubimage2d_rgb888( struct gl_texture_convert
*convert
)
241 /* This is a placeholder for now...
247 convert_texsubimage3d_rgb888( struct gl_texture_convert
*convert
)
249 /* This is a placeholder for now...
256 /* =============================================================
260 #define DST_TYPE GLushort
261 #define DST_TEXELS_PER_DWORD 2
263 #define CONVERT_TEXEL( dst, src ) \
264 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
266 #define CONVERT_DIRECT
268 #define SRC_TEXEL_BYTES 2
270 #define TAG(x) x##_rgb565_direct
271 #define PRESERVE_DST_TYPE
272 #include "texutil_tmp.h"
275 #define CONVERT_TEXEL( dst, src ) \
276 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
278 #define CONVERT_TEXEL_DWORD( dst, src ) \
279 dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
280 PACK_COLOR_565_LE( src[3], src[4], src[5] ) )
282 #define SRC_TEXEL_BYTES 3
284 #define TAG(x) x##_bgr888_to_rgb565
285 #define PRESERVE_DST_TYPE
286 #include "texutil_tmp.h"
289 #define CONVERT_TEXEL( dst, src ) \
290 dst = PACK_COLOR_565_LE( src[0], src[1], src[2] )
292 #define CONVERT_TEXEL_DWORD( dst, src ) \
293 dst = APPEND16( PACK_COLOR_565_LE( src[0], src[1], src[2] ), \
294 PACK_COLOR_565_LE( src[4], src[5], src[6] ) )
296 #define SRC_TEXEL_BYTES 4
298 #define TAG(x) x##_abgr8888_to_rgb565
299 #include "texutil_tmp.h"
302 #define CONVERT_RGB565( name ) \
304 convert_##name##_rgb565( struct gl_texture_convert *convert ) \
307 GLint index = convert->index; \
309 if ( convert->format == GL_RGB && \
310 convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
312 tab = name##_tab_rgb565_direct; \
314 else if ( convert->format == GL_RGB && \
315 convert->type == GL_UNSIGNED_BYTE ) \
317 tab = name##_tab_bgr888_to_rgb565; \
319 else if ( convert->format == GL_RGBA && \
320 convert->type == GL_UNSIGNED_BYTE ) \
322 tab = name##_tab_abgr8888_to_rgb565; \
326 /* Can't handle this source format/type combination */ \
330 return tab[index]( convert ); \
333 CONVERT_RGB565( texsubimage2d
)
334 CONVERT_RGB565( texsubimage3d
)
338 /* =============================================================
342 #define DST_TYPE GLushort
343 #define DST_TEXELS_PER_DWORD 2
345 #define CONVERT_TEXEL( dst, src ) \
346 dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
348 #define CONVERT_DIRECT
350 #define SRC_TEXEL_BYTES 2
352 #define TAG(x) x##_argb4444_direct
353 #define PRESERVE_DST_TYPE
354 #include "texutil_tmp.h"
357 #define CONVERT_TEXEL( dst, src ) \
358 dst = PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] )
360 #define CONVERT_TEXEL_DWORD( dst, src ) \
361 dst = APPEND16( PACK_COLOR_4444_LE( src[3], src[0], src[1], src[2] ), \
362 PACK_COLOR_4444_LE( src[7], src[4], src[5], src[6] ) )
364 #define SRC_TEXEL_BYTES 4
366 #define TAG(x) x##_abgr8888_to_argb4444
367 #include "texutil_tmp.h"
370 #define CONVERT_ARGB4444( name ) \
372 convert_##name##_argb4444( struct gl_texture_convert *convert ) \
375 GLint index = convert->index; \
377 if ( convert->format == GL_BGRA && \
378 convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
380 tab = name##_tab_argb4444_direct; \
382 else if ( convert->format == GL_RGBA && \
383 convert->type == GL_UNSIGNED_BYTE ) \
385 tab = name##_tab_abgr8888_to_argb4444; \
389 /* Can't handle this source format/type combination */ \
393 return tab[index]( convert ); \
396 CONVERT_ARGB4444( texsubimage2d
)
397 CONVERT_ARGB4444( texsubimage3d
)
401 /* =============================================================
405 #define DST_TYPE GLushort
406 #define DST_TEXELS_PER_DWORD 2
408 #define CONVERT_TEXEL( dst, src ) \
409 dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
411 #define CONVERT_DIRECT
413 #define SRC_TEXEL_BYTES 2
415 #define TAG(x) x##_argb1555_direct
416 #define PRESERVE_DST_TYPE
417 #include "texutil_tmp.h"
420 #ifdef MESA_BIG_ENDIAN
422 #define CONVERT_TEXEL( dst, src ) \
423 { const GLushort s = *(GLushort *)src; \
424 dst = (s >> 9) | ((s & 0x1ff) << 7); }
426 #define CONVERT_TEXEL_DWORD( dst, src ) \
427 { const GLuint s = ((fi_type *)src)->i; \
428 dst = (((s & 0xfe00fe00) >> 9) | \
429 ((s & 0x01ff01ff) << 7)); }
433 #define CONVERT_TEXEL( dst, src ) \
434 { const GLushort s = *(GLushort *)src; \
435 dst = (s >> 1) | ((s & 1) << 15); }
437 #define CONVERT_TEXEL_DWORD( dst, src ) \
438 { const GLuint s = ((fi_type *)src)->i; \
439 dst = (((s & 0xfffefffe) >> 1) | \
440 ((s & 0x00010001) << 15)); }
444 #define SRC_TEXEL_BYTES 2
446 #define TAG(x) x##_rgba5551_to_argb1555
447 #define PRESERVE_DST_TYPE
448 #include "texutil_tmp.h"
451 #define CONVERT_TEXEL( dst, src ) \
452 dst = PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] )
454 #define CONVERT_TEXEL_DWORD( dst, src ) \
455 dst = APPEND16( PACK_COLOR_1555_LE( src[3], src[0], src[1], src[2] ), \
456 PACK_COLOR_1555_LE( src[7], src[4], src[5], src[6] ) )
458 #define SRC_TEXEL_BYTES 4
460 #define TAG(x) x##_abgr8888_to_argb1555
461 #include "texutil_tmp.h"
464 #define CONVERT_ARGB1555( name ) \
466 convert_##name##_argb1555( struct gl_texture_convert *convert ) \
469 GLint index = convert->index; \
471 if ( convert->format == GL_BGRA && \
472 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
474 tab = name##_tab_argb1555_direct; \
476 else if ( convert->format == GL_RGBA && \
477 convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \
479 tab = name##_tab_rgba5551_to_argb1555; \
481 else if ( convert->format == GL_RGBA && \
482 convert->type == GL_UNSIGNED_BYTE ) \
484 tab = name##_tab_abgr8888_to_argb1555; \
488 /* Can't handle this source format/type combination */ \
492 return tab[index]( convert ); \
495 CONVERT_ARGB1555( texsubimage2d
)
496 CONVERT_ARGB1555( texsubimage3d
)
500 /* =============================================================
504 #define DST_TYPE GLushort
505 #define DST_TEXELS_PER_DWORD 2
507 #define CONVERT_TEXEL( dst, src ) \
508 dst = PACK_COLOR_88_LE( src[0], src[1] )
510 #define CONVERT_DIRECT
512 #define SRC_TEXEL_BYTES 2
514 #define TAG(x) x##_al88_direct
515 #define PRESERVE_DST_TYPE
516 #include "texutil_tmp.h"
519 #define CONVERT_TEXEL( dst, src ) \
520 dst = PACK_COLOR_88_LE( src[0], 0x00 )
522 #define CONVERT_TEXEL_DWORD( dst, src ) \
523 dst = APPEND16( PACK_COLOR_88_LE( src[0], 0x00 ), \
524 PACK_COLOR_88_LE( src[1], 0x00 ) )
526 #define SRC_TEXEL_BYTES 1
528 #define TAG(x) x##_a8_to_al88
529 #define PRESERVE_DST_TYPE
530 #include "texutil_tmp.h"
533 #define CONVERT_TEXEL( dst, src ) \
534 dst = PACK_COLOR_88_LE( 0xff, src[0] )
536 #define CONVERT_TEXEL_DWORD( dst, src ) \
537 dst = APPEND16( PACK_COLOR_88_LE( 0xff, src[0] ), \
538 PACK_COLOR_88_LE( 0xff, src[1] ) )
540 #define SRC_TEXEL_BYTES 1
542 #define TAG(x) x##_l8_to_al88
543 #define PRESERVE_DST_TYPE
544 #include "texutil_tmp.h"
547 #define CONVERT_TEXEL( dst, src ) \
548 dst = PACK_COLOR_88_LE( src[3], src[0] )
550 #define CONVERT_TEXEL_DWORD( dst, src ) \
551 dst = APPEND16( PACK_COLOR_88_LE( src[3], src[0] ), \
552 PACK_COLOR_88_LE( src[7], src[4] ) )
554 #define SRC_TEXEL_BYTES 4
556 #define TAG(x) x##_abgr8888_to_al88
557 #include "texutil_tmp.h"
560 #define CONVERT_AL88( name ) \
562 convert_##name##_al88( struct gl_texture_convert *convert ) \
565 GLint index = convert->index; \
567 if ( convert->format == GL_LUMINANCE_ALPHA && \
568 convert->type == GL_UNSIGNED_BYTE ) \
570 tab = name##_tab_al88_direct; \
572 else if ( convert->format == GL_ALPHA && \
573 convert->type == GL_UNSIGNED_BYTE ) \
575 tab = name##_tab_a8_to_al88; \
577 else if ( convert->format == GL_LUMINANCE && \
578 convert->type == GL_UNSIGNED_BYTE ) \
580 tab = name##_tab_l8_to_al88; \
582 else if ( convert->format == GL_RGBA && \
583 convert->type == GL_UNSIGNED_BYTE ) \
585 tab = name##_tab_abgr8888_to_al88; \
589 /* Can't handle this source format/type combination */ \
593 return tab[index]( convert ); \
596 CONVERT_AL88( texsubimage2d
)
597 CONVERT_AL88( texsubimage3d
)
601 /* =============================================================
606 convert_texsubimage2d_rgb332( struct gl_texture_convert
*convert
)
608 /* This is a placeholder for now...
614 convert_texsubimage3d_rgb332( struct gl_texture_convert
*convert
)
616 /* This is a placeholder for now...
623 /* =============================================================
624 * CI8 (and all other single-byte texel) textures:
627 #define DST_TYPE GLubyte
628 #define DST_TEXELS_PER_DWORD 4
630 #define CONVERT_TEXEL( dst, src ) dst = src[0]
632 #define CONVERT_DIRECT
634 #define SRC_TEXEL_BYTES 1
636 #define TAG(x) x##_ci8_direct
637 #include "texutil_tmp.h"
640 #define CONVERT_CI8( name ) \
642 convert_##name##_ci8( struct gl_texture_convert *convert ) \
645 GLint index = convert->index; \
647 if ( ( convert->format == GL_ALPHA || \
648 convert->format == GL_LUMINANCE || \
649 convert->format == GL_INTENSITY || \
650 convert->format == GL_COLOR_INDEX ) && \
651 convert->type == GL_UNSIGNED_BYTE ) \
653 tab = name##_tab_ci8_direct; \
657 /* Can't handle this source format/type combination */ \
661 return tab[index]( convert ); \
664 CONVERT_CI8( texsubimage2d
)
665 CONVERT_CI8( texsubimage3d
)
669 /* =============================================================
670 * Global entry points
673 static convert_func gl_convert_texsubimage2d_tab
[] = {
674 convert_texsubimage2d_rgba8888
,
675 convert_texsubimage2d_argb8888
,
676 convert_texsubimage2d_rgb888
,
677 convert_texsubimage2d_rgb565
,
678 convert_texsubimage2d_argb4444
,
679 convert_texsubimage2d_argb1555
,
680 convert_texsubimage2d_al88
,
681 convert_texsubimage2d_rgb332
,
682 convert_texsubimage2d_ci8
, /* These are all the same... */
683 convert_texsubimage2d_ci8
,
684 convert_texsubimage2d_ci8
,
685 convert_texsubimage2d_ci8
,
688 static convert_func gl_convert_texsubimage3d_tab
[] = {
689 convert_texsubimage3d_rgba8888
,
690 convert_texsubimage3d_argb8888
,
691 convert_texsubimage3d_rgb888
,
692 convert_texsubimage3d_rgb565
,
693 convert_texsubimage3d_argb4444
,
694 convert_texsubimage3d_argb1555
,
695 convert_texsubimage3d_al88
,
696 convert_texsubimage3d_rgb332
,
697 convert_texsubimage3d_ci8
, /* These are all the same... */
698 convert_texsubimage3d_ci8
,
699 convert_texsubimage3d_ci8
,
700 convert_texsubimage3d_ci8
,
704 /* See if we need to care about the pixel store attributes when we're
705 * converting the texture image. This should be stored as
706 * unpacking->_SomeBoolean and updated when the values change, to avoid
707 * testing every time...
709 static INLINE GLboolean
710 convert_needs_unpacking( const struct gl_pixelstore_attrib
*unpacking
,
711 GLenum format
, GLenum type
)
713 if ( ( unpacking
->Alignment
== 1 ||
714 ( unpacking
->Alignment
== 4 && /* Pick up the common Q3A case... */
715 format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) ) &&
716 unpacking
->RowLength
== 0 &&
717 unpacking
->SkipPixels
== 0 &&
718 unpacking
->SkipRows
== 0 &&
719 unpacking
->ImageHeight
== 0 &&
720 unpacking
->SkipImages
== 0 &&
721 unpacking
->SwapBytes
== GL_FALSE
&&
722 unpacking
->LsbFirst
== GL_FALSE
) {
731 _mesa_convert_texsubimage1d( GLint mesaFormat
,
734 GLenum format
, GLenum type
,
735 const struct gl_pixelstore_attrib
*unpacking
,
736 const GLvoid
*srcImage
, GLvoid
*dstImage
)
738 struct gl_texture_convert convert
;
744 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
745 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
747 /* Make it easier to pass all the parameters around.
749 convert
.xoffset
= xoffset
;
751 convert
.width
= width
;
753 convert
.format
= format
;
755 convert
.unpacking
= unpacking
;
756 convert
.srcImage
= srcImage
;
757 convert
.dstImage
= dstImage
;
761 if ( convert_needs_unpacking( unpacking
, format
, type
) )
762 convert
.index
|= CONVERT_UNPACKING_BIT
;
764 return gl_convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
768 /* Convert a user's 2D image into a texture image. This basically
769 * repacks pixel data into the special texture formats used by core Mesa
770 * and the DRI drivers. This function can do full images or subimages.
772 * We return a boolean because this function may not accept some kinds
773 * of source image formats and/or types. For example, if the incoming
774 * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
775 * be able to do the conversion.
777 * In that case, the incoming image should first be simplified to one of
778 * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
779 * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
780 * with the _mesa_transfer_teximage() function. That function will also
781 * do image transfer operations such as scale/bias and convolution.
784 * mesaFormat - one of the MESA_FORMAT_* values from texformat.h
785 * xoffset, yoffset - position in dest image to put data
786 * width, height - incoming image size, also size of dest region.
787 * dstImageWidth - width (row stride) of dest image in pixels
788 * format, type - incoming image format and type
789 * unpacking - describes incoming image unpacking
790 * srcImage - pointer to source image
791 * destImage - pointer to dest image
794 _mesa_convert_texsubimage2d( GLint mesaFormat
,
795 GLint xoffset
, GLint yoffset
,
796 GLint width
, GLint height
,
797 GLint destImageWidth
,
798 GLenum format
, GLenum type
,
799 const struct gl_pixelstore_attrib
*unpacking
,
800 const GLvoid
*srcImage
, GLvoid
*dstImage
)
802 struct gl_texture_convert convert
;
808 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
809 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
811 /* Make it easier to pass all the parameters around.
813 convert
.xoffset
= xoffset
;
814 convert
.yoffset
= yoffset
;
815 convert
.width
= width
;
816 convert
.height
= height
;
817 convert
.dstImageWidth
= destImageWidth
;
818 convert
.format
= format
;
820 convert
.unpacking
= unpacking
;
821 convert
.srcImage
= srcImage
;
822 convert
.dstImage
= dstImage
;
826 if ( convert_needs_unpacking( unpacking
, format
, type
) )
827 convert
.index
|= CONVERT_UNPACKING_BIT
;
829 if ( width
!= destImageWidth
)
830 convert
.index
|= CONVERT_STRIDE_BIT
;
832 return gl_convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
836 _mesa_convert_texsubimage3d( GLint mesaFormat
,
837 GLint xoffset
, GLint yoffset
, GLint zoffset
,
838 GLint width
, GLint height
, GLint depth
,
839 GLint dstImageWidth
, GLint dstImageHeight
,
840 GLenum format
, GLenum type
,
841 const struct gl_pixelstore_attrib
*unpacking
,
842 const GLvoid
*srcImage
, GLvoid
*dstImage
)
844 struct gl_texture_convert convert
;
850 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
851 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
853 /* Make it easier to pass all the parameters around.
855 convert
.xoffset
= xoffset
;
856 convert
.yoffset
= yoffset
;
857 convert
.zoffset
= zoffset
;
858 convert
.width
= width
;
859 convert
.height
= height
;
860 convert
.depth
= depth
;
861 convert
.dstImageWidth
= dstImageWidth
;
862 convert
.dstImageHeight
= dstImageHeight
;
863 convert
.format
= format
;
865 convert
.unpacking
= unpacking
;
866 convert
.srcImage
= srcImage
;
867 convert
.dstImage
= dstImage
;
871 if ( convert_needs_unpacking( unpacking
, format
, type
) )
872 convert
.index
|= CONVERT_UNPACKING_BIT
;
874 if ( width
!= dstImageWidth
|| height
!= dstImageHeight
)
875 convert
.index
|= CONVERT_STRIDE_BIT
;
877 return gl_convert_texsubimage3d_tab
[mesaFormat
]( &convert
);
882 /* Nearest filtering only (for broken hardware that can't support
883 * all aspect ratios). This can be made a lot faster, but I don't
884 * really care enough...
886 void _mesa_rescale_teximage2d( GLuint bytesPerPixel
, GLuint dstRowStride
,
887 GLint srcWidth
, GLint srcHeight
,
888 GLint dstWidth
, GLint dstHeight
,
889 const GLvoid
*srcImage
, GLvoid
*dstImage
)
893 #define INNER_LOOP( TYPE, HOP, WOP ) \
894 for ( row = 0 ; row < dstHeight ; row++ ) { \
895 GLint srcRow = row HOP hScale; \
896 for ( col = 0 ; col < dstWidth ; col++ ) { \
897 GLint srcCol = col WOP wScale; \
898 dst[col] = src[srcRow * srcWidth + srcCol]; \
900 dst = (TYPE *) ((GLubyte *) dst + dstRowStride); \
903 #define RESCALE_IMAGE( TYPE ) \
905 const TYPE *src = (const TYPE *)srcImage; \
906 TYPE *dst = (TYPE *)dstImage; \
908 if ( srcHeight <= dstHeight ) { \
909 const GLint hScale = dstHeight / srcHeight; \
910 if ( srcWidth <= dstWidth ) { \
911 const GLint wScale = dstWidth / srcWidth; \
912 INNER_LOOP( TYPE, /, / ); \
915 const GLint wScale = srcWidth / dstWidth; \
916 INNER_LOOP( TYPE, /, * ); \
920 const GLint hScale = srcHeight / dstHeight; \
921 if ( srcWidth <= dstWidth ) { \
922 const GLint wScale = dstWidth / srcWidth; \
923 INNER_LOOP( TYPE, *, / ); \
926 const GLint wScale = srcWidth / dstWidth; \
927 INNER_LOOP( TYPE, *, * ); \
932 switch ( bytesPerPixel
) {
934 RESCALE_IMAGE( GLuint
);
938 RESCALE_IMAGE( GLushort
);
942 RESCALE_IMAGE( GLubyte
);
945 _mesa_problem(NULL
,"unexpected bytes/pixel in _mesa_rescale_teximage2d");