1 /* $Id: texutil.c,v 1.20 2001/03/27 20:32:24 brianp Exp $ */
4 * Mesa 3-D graphics library
7 * Copyright (C) 1999-2001 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"
47 struct gl_texture_convert
{
48 GLint xoffset
, yoffset
, zoffset
; /* Subimage offset */
49 GLint width
, height
, depth
; /* Subimage region */
51 GLint dstImageWidth
, dstImageHeight
; /* Dest image size */
52 /* Needed for subimage replacement */
53 GLenum format
, type
; /* Source (user) format and type */
55 const struct gl_pixelstore_attrib
*packing
;
57 const GLvoid
*srcImage
;
63 typedef GLboolean (*convert_func
)( struct gl_texture_convert
*convert
);
65 #define CONVERT_STRIDE_BIT 0x1
66 #define CONVERT_PACKING_BIT 0x2
70 /* ================================================================
74 #define DST_TYPE GLuint
75 #define DST_TEXELS_PER_DWORD 1
77 #define CONVERT_TEXEL( dst, src ) \
78 dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
80 #define CONVERT_DIRECT
82 #define SRC_TEXEL_BYTES 4
84 #define TAG(x) x##_rgba8888_direct
85 #define PRESERVE_DST_TYPE
86 #include "texutil_tmp.h"
89 #define CONVERT_TEXEL( dst, src ) \
90 dst = PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
92 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
94 #define SRC_TEXEL_BYTES 4
96 #define TAG(x) x##_abgr8888_to_rgba8888
97 #define PRESERVE_DST_TYPE
98 #include "texutil_tmp.h"
101 #define CONVERT_TEXEL( dst, src ) \
102 dst = PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
104 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
106 #define SRC_TEXEL_BYTES 3
108 #define TAG(x) x##_bgr888_to_rgba8888
109 #include "texutil_tmp.h"
112 #define CONVERT_RGBA8888( name ) \
114 convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
117 GLint index = convert->index; \
119 if ( convert->format == GL_ABGR_EXT && \
120 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
122 tab = name##_tab_rgba8888_direct; \
124 else if ( convert->format == GL_RGBA && \
125 ( convert->type == GL_UNSIGNED_BYTE || \
126 convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
128 tab = name##_tab_abgr8888_to_rgba8888; \
130 else if ( convert->format == GL_RGB && \
131 convert->type == GL_UNSIGNED_BYTE ) \
133 tab = name##_tab_bgr888_to_rgba8888; \
137 /* Can't handle this source format/type combination */ \
141 return tab[index]( convert ); \
144 CONVERT_RGBA8888( texsubimage2d
)
145 CONVERT_RGBA8888( texsubimage3d
)
149 /* ================================================================
153 #define DST_TYPE GLuint
154 #define DST_TEXELS_PER_DWORD 1
156 #define CONVERT_TEXEL( dst, src ) \
157 dst = PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
159 #define CONVERT_DIRECT
161 #define SRC_TEXEL_BYTES 4
163 #define TAG(x) x##_argb8888_direct
164 #define PRESERVE_DST_TYPE
165 #include "texutil_tmp.h"
168 #define CONVERT_TEXEL( dst, src ) \
169 dst = PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
171 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
173 #define SRC_TEXEL_BYTES 4
175 #define TAG(x) x##_abgr8888_to_argb8888
176 #define PRESERVE_DST_TYPE
177 #include "texutil_tmp.h"
180 #define CONVERT_TEXEL( dst, src ) \
181 dst = PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
183 #define CONVERT_TEXEL_DWORD( dst, src ) CONVERT_TEXEL( dst, src )
185 #define SRC_TEXEL_BYTES 3
187 #define TAG(x) x##_bgr888_to_argb8888
188 #include "texutil_tmp.h"
191 #define CONVERT_ARGB8888( name ) \
193 convert_##name##_argb8888( struct gl_texture_convert *convert ) \
196 GLint index = convert->index; \
198 if ( convert->format == GL_BGRA && \
199 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
201 tab = name##_tab_argb8888_direct; \
203 else if ( convert->format == GL_RGBA && \
204 convert->type == GL_UNSIGNED_BYTE ) \
206 tab = name##_tab_abgr8888_to_argb8888; \
208 else if ( convert->format == GL_RGB && \
209 convert->type == GL_UNSIGNED_BYTE ) \
211 tab = name##_tab_bgr888_to_argb8888; \
215 /* Can't handle this source format/type combination */ \
219 return tab[index]( convert ); \
222 CONVERT_ARGB8888( texsubimage2d
)
223 CONVERT_ARGB8888( texsubimage3d
)
227 /* ================================================================
232 convert_texsubimage2d_rgb888( struct gl_texture_convert
*convert
)
234 /* This is a placeholder for now...
240 convert_texsubimage3d_rgb888( struct gl_texture_convert
*convert
)
242 /* This is a placeholder for now...
249 /* ================================================================
253 #define DST_TYPE GLushort
254 #define DST_TEXELS_PER_DWORD 2
256 #define CONVERT_TEXEL( dst, src ) \
257 dst = PACK_COLOR_565( src[0], src[1], src[2] )
259 #define CONVERT_DIRECT
261 #define SRC_TEXEL_BYTES 2
263 #define TAG(x) x##_rgb565_direct
264 #define PRESERVE_DST_TYPE
265 #include "texutil_tmp.h"
268 #define CONVERT_TEXEL( dst, src ) \
269 dst = PACK_COLOR_565( src[0], src[1], src[2] )
271 #define CONVERT_TEXEL_DWORD( dst, src ) \
272 dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
273 (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
275 #define SRC_TEXEL_BYTES 3
277 #define TAG(x) x##_bgr888_to_rgb565
278 #define PRESERVE_DST_TYPE
279 #include "texutil_tmp.h"
282 #define CONVERT_TEXEL( dst, src ) \
283 dst = PACK_COLOR_565( src[0], src[1], src[2] )
285 #define CONVERT_TEXEL_DWORD( dst, src ) \
286 dst = ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
287 (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
289 #define SRC_TEXEL_BYTES 4
291 #define TAG(x) x##_abgr8888_to_rgb565
292 #include "texutil_tmp.h"
295 #define CONVERT_RGB565( name ) \
297 convert_##name##_rgb565( struct gl_texture_convert *convert ) \
300 GLint index = convert->index; \
302 if ( convert->format == GL_RGB && \
303 convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
305 tab = name##_tab_rgb565_direct; \
307 else if ( convert->format == GL_RGB && \
308 convert->type == GL_UNSIGNED_BYTE ) \
310 tab = name##_tab_bgr888_to_rgb565; \
312 else if ( convert->format == GL_RGBA && \
313 convert->type == GL_UNSIGNED_BYTE ) \
315 tab = name##_tab_abgr8888_to_rgb565; \
319 /* Can't handle this source format/type combination */ \
323 return tab[index]( convert ); \
326 CONVERT_RGB565( texsubimage2d
)
327 CONVERT_RGB565( texsubimage3d
)
331 /* ================================================================
335 #define DST_TYPE GLushort
336 #define DST_TEXELS_PER_DWORD 2
338 #define CONVERT_TEXEL( dst, src ) \
339 dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
341 #define CONVERT_DIRECT
343 #define SRC_TEXEL_BYTES 2
345 #define TAG(x) x##_argb4444_direct
346 #define PRESERVE_DST_TYPE
347 #include "texutil_tmp.h"
350 #define CONVERT_TEXEL( dst, src ) \
351 dst = PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
353 #define CONVERT_TEXEL_DWORD( dst, src ) \
354 dst = ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) |\
355 (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
357 #define SRC_TEXEL_BYTES 4
359 #define TAG(x) x##_rgba8888_to_argb4444
360 #include "texutil_tmp.h"
363 #define CONVERT_ARGB4444( name ) \
365 convert_##name##_argb4444( struct gl_texture_convert *convert ) \
368 GLint index = convert->index; \
370 if ( convert->format == GL_BGRA && \
371 convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
373 tab = name##_tab_argb4444_direct; \
375 else if ( convert->format == GL_RGBA && \
376 convert->type == GL_UNSIGNED_BYTE ) \
378 tab = name##_tab_rgba8888_to_argb4444; \
382 /* Can't handle this source format/type combination */ \
386 return tab[index]( convert ); \
389 CONVERT_ARGB4444( texsubimage2d
)
390 CONVERT_ARGB4444( texsubimage3d
)
394 /* ================================================================
398 #define DST_TYPE GLushort
399 #define DST_TEXELS_PER_DWORD 2
401 #define CONVERT_TEXEL( dst, src ) \
402 dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
404 #define CONVERT_DIRECT
406 #define SRC_TEXEL_BYTES 2
408 #define TAG(x) x##_argb1555_direct
409 #define PRESERVE_DST_TYPE
410 #include "texutil_tmp.h"
413 #define CONVERT_TEXEL( dst, src ) \
414 { const GLushort s = *(GLushort *)src; \
415 dst = (s >> 1) | ((s & 1) << 15); }
417 #define CONVERT_TEXEL_DWORD( dst, src ) \
418 { const GLuint s = *(GLuint *)src; \
419 dst = (((s & 0xfffefffe) >> 1) | \
420 ((s & 0x00010001) << 15)); }
422 #define SRC_TEXEL_BYTES 2
424 #define TAG(x) x##_rgba5551_to_argb1555
425 #define PRESERVE_DST_TYPE
426 #include "texutil_tmp.h"
429 #define CONVERT_TEXEL( dst, src ) \
430 dst = PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
432 #define CONVERT_TEXEL_DWORD( dst, src ) \
433 dst = ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) |\
434 (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
436 #define SRC_TEXEL_BYTES 4
438 #define TAG(x) x##_rgba8888_to_argb1555
439 #include "texutil_tmp.h"
442 #define CONVERT_ARGB1555( name ) \
444 convert_##name##_argb1555( struct gl_texture_convert *convert ) \
447 GLint index = convert->index; \
449 if ( convert->format == GL_BGRA && \
450 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
452 tab = name##_tab_argb1555_direct; \
454 else if ( convert->format == GL_RGBA && \
455 convert->type == GL_UNSIGNED_SHORT_5_5_5_1 ) \
457 tab = name##_tab_rgba5551_to_argb1555; \
459 else if ( convert->format == GL_RGBA && \
460 convert->type == GL_UNSIGNED_BYTE ) \
462 tab = name##_tab_rgba8888_to_argb1555; \
466 /* Can't handle this source format/type combination */ \
470 return tab[index]( convert ); \
473 CONVERT_ARGB1555( texsubimage2d
)
474 CONVERT_ARGB1555( texsubimage3d
)
478 /* ================================================================
482 #define DST_TYPE GLushort
483 #define DST_TEXELS_PER_DWORD 2
485 #define CONVERT_TEXEL( dst, src ) \
486 dst = PACK_COLOR_88( src[0], src[1] )
488 #define CONVERT_DIRECT
490 #define SRC_TEXEL_BYTES 2
492 #define TAG(x) x##_al88_direct
493 #define PRESERVE_DST_TYPE
494 #include "texutil_tmp.h"
497 #define CONVERT_TEXEL( dst, src ) \
498 dst = PACK_COLOR_88( src[0], 0x00 )
500 #define CONVERT_TEXEL_DWORD( dst, src ) \
501 dst = ((PACK_COLOR_88( src[0], 0x00 )) | \
502 (PACK_COLOR_88( src[1], 0x00 ) << 16))
504 #define SRC_TEXEL_BYTES 1
506 #define TAG(x) x##_a8_to_al88
507 #define PRESERVE_DST_TYPE
508 #include "texutil_tmp.h"
511 #define CONVERT_TEXEL( dst, src ) \
512 dst = PACK_COLOR_88( 0xff, src[0] )
514 #define CONVERT_TEXEL_DWORD( dst, src ) \
515 dst = ((PACK_COLOR_88( 0xff, src[0] )) | \
516 (PACK_COLOR_88( 0xff, src[1] ) << 16))
518 #define SRC_TEXEL_BYTES 1
520 #define TAG(x) x##_l8_to_al88
521 #define PRESERVE_DST_TYPE
522 #include "texutil_tmp.h"
525 #define CONVERT_TEXEL( dst, src ) \
526 dst = PACK_COLOR_88( src[3], src[0] )
528 #define CONVERT_TEXEL_DWORD( dst, src ) \
529 dst = ((PACK_COLOR_88( src[3], src[0] )) | \
530 (PACK_COLOR_88( src[7], src[1] ) << 16))
532 #define SRC_TEXEL_BYTES 4
534 #define TAG(x) x##_abgr8888_to_al88
535 #include "texutil_tmp.h"
538 #define CONVERT_AL88( name ) \
540 convert_##name##_al88( struct gl_texture_convert *convert ) \
543 GLint index = convert->index; \
545 if ( convert->format == GL_LUMINANCE_ALPHA && \
546 convert->type == GL_UNSIGNED_BYTE ) \
548 tab = name##_tab_al88_direct; \
550 else if ( convert->format == GL_ALPHA && \
551 convert->type == GL_UNSIGNED_BYTE ) \
553 tab = name##_tab_a8_to_al88; \
555 else if ( convert->format == GL_LUMINANCE && \
556 convert->type == GL_UNSIGNED_BYTE ) \
558 tab = name##_tab_l8_to_al88; \
560 else if ( convert->format == GL_RGBA && \
561 convert->type == GL_UNSIGNED_BYTE ) \
563 tab = name##_tab_abgr8888_to_al88; \
567 /* Can't handle this source format/type combination */ \
571 return tab[index]( convert ); \
574 CONVERT_AL88( texsubimage2d
)
575 CONVERT_AL88( texsubimage3d
)
579 /* ================================================================
584 convert_texsubimage2d_rgb332( struct gl_texture_convert
*convert
)
586 /* This is a placeholder for now...
592 convert_texsubimage3d_rgb332( struct gl_texture_convert
*convert
)
594 /* This is a placeholder for now...
601 /* ================================================================
602 * CI8 (and all other single-byte texel) textures:
605 #define DST_TYPE GLubyte
606 #define DST_TEXELS_PER_DWORD 4
608 #define CONVERT_TEXEL( dst, src ) dst = src[0]
610 #define CONVERT_DIRECT
612 #define SRC_TEXEL_BYTES 1
614 #define TAG(x) x##_ci8_direct
615 #include "texutil_tmp.h"
618 #define CONVERT_CI8( name ) \
620 convert_##name##_ci8( struct gl_texture_convert *convert ) \
623 GLint index = convert->index; \
625 if ( ( convert->format == GL_ALPHA || \
626 convert->format == GL_LUMINANCE || \
627 convert->format == GL_INTENSITY || \
628 convert->format == GL_COLOR_INDEX ) && \
629 convert->type == GL_UNSIGNED_BYTE ) \
631 tab = name##_tab_ci8_direct; \
635 /* Can't handle this source format/type combination */ \
639 return tab[index]( convert ); \
642 CONVERT_CI8( texsubimage2d
)
643 CONVERT_CI8( texsubimage3d
)
647 /* ================================================================
648 * Global entry points
651 static convert_func gl_convert_texsubimage2d_tab
[] = {
652 convert_texsubimage2d_rgba8888
,
653 convert_texsubimage2d_argb8888
,
654 convert_texsubimage2d_rgb888
,
655 convert_texsubimage2d_rgb565
,
656 convert_texsubimage2d_argb4444
,
657 convert_texsubimage2d_argb1555
,
658 convert_texsubimage2d_al88
,
659 convert_texsubimage2d_rgb332
,
660 convert_texsubimage2d_ci8
, /* These are all the same... */
661 convert_texsubimage2d_ci8
,
662 convert_texsubimage2d_ci8
,
663 convert_texsubimage2d_ci8
,
666 static convert_func gl_convert_texsubimage3d_tab
[] = {
667 convert_texsubimage3d_rgba8888
,
668 convert_texsubimage3d_argb8888
,
669 convert_texsubimage3d_rgb888
,
670 convert_texsubimage3d_rgb565
,
671 convert_texsubimage3d_argb4444
,
672 convert_texsubimage3d_argb1555
,
673 convert_texsubimage3d_al88
,
674 convert_texsubimage3d_rgb332
,
675 convert_texsubimage3d_ci8
, /* These are all the same... */
676 convert_texsubimage3d_ci8
,
677 convert_texsubimage3d_ci8
,
678 convert_texsubimage3d_ci8
,
682 /* See if we need to care about the pixel store attributes when we're
683 * converting the texture image. This should be stored as
684 * packing->_SomeBoolean and updated when the values change, to avoid
685 * testing every time...
687 static INLINE GLboolean
688 convert_needs_packing( const struct gl_pixelstore_attrib
*packing
,
689 GLenum format
, GLenum type
)
691 if ( ( packing
->Alignment
== 1 ||
692 ( packing
->Alignment
== 4 && /* Pick up the common Q3A case... */
693 format
== GL_RGBA
&& type
== GL_UNSIGNED_BYTE
) ) &&
694 packing
->RowLength
== 0 &&
695 packing
->SkipPixels
== 0 &&
696 packing
->SkipRows
== 0 &&
697 packing
->ImageHeight
== 0 &&
698 packing
->SkipImages
== 0 &&
699 packing
->SwapBytes
== GL_FALSE
&&
700 packing
->LsbFirst
== GL_FALSE
) {
709 _mesa_convert_texsubimage1d( GLint mesaFormat
,
712 GLenum format
, GLenum type
,
713 const struct gl_pixelstore_attrib
*packing
,
714 const GLvoid
*srcImage
, GLvoid
*dstImage
)
716 struct gl_texture_convert convert
;
722 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
723 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
725 /* Make it easier to pass all the parameters around.
727 convert
.xoffset
= xoffset
;
729 convert
.width
= width
;
731 convert
.format
= format
;
733 convert
.packing
= packing
;
734 convert
.srcImage
= srcImage
;
735 convert
.dstImage
= dstImage
;
739 if ( convert_needs_packing( packing
, format
, type
) )
740 convert
.index
|= CONVERT_PACKING_BIT
;
742 return gl_convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
747 * Convert a user's 2D image into a texture image. This basically repacks
748 * pixel data into the special texture formats used by core Mesa and the DRI
749 * drivers. This function can do full images or subimages.
751 * We return a boolean because this function may not accept some kinds of
752 * source image formats and/or types. For example, if the incoming
753 * format/type = GL_BGR, GL_UNSIGNED_INT this function probably won't
754 * be able to do the conversion.
756 * In that case, the incoming image should first be simplified to one of
757 * the "canonical" formats (GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA,
758 * GL_INTENSITY, GL_RGB, GL_RGBA) and types (GL_CHAN). We can do that
759 * with the _mesa_transfer_teximage() function. That function will also
760 * do image transfer operations such as scale/bias and convolution.
763 * mesaFormat - one of the MESA_FORMAT_* values from texformat.h
764 * xoffset, yoffset - position in dest image to put data
765 * width, height - incoming image size, also size of dest region.
766 * dstImageWidth - width (row stride) of dest image in pixels
767 * format, type - incoming image format and type
768 * packing - describes incoming image packing
769 * srcImage - pointer to source image
770 * destImage - pointer to dest image
773 _mesa_convert_texsubimage2d( GLint mesaFormat
,
774 GLint xoffset
, GLint yoffset
,
775 GLint width
, GLint height
,
776 GLint destImageWidth
,
777 GLenum format
, GLenum type
,
778 const struct gl_pixelstore_attrib
*packing
,
779 const GLvoid
*srcImage
, GLvoid
*dstImage
)
781 struct gl_texture_convert convert
;
787 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
788 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
790 /* Make it easier to pass all the parameters around.
792 convert
.xoffset
= xoffset
;
793 convert
.yoffset
= yoffset
;
794 convert
.width
= width
;
795 convert
.height
= height
;
796 convert
.dstImageWidth
= destImageWidth
;
797 convert
.format
= format
;
799 convert
.packing
= packing
;
800 convert
.srcImage
= srcImage
;
801 convert
.dstImage
= dstImage
;
805 if ( convert_needs_packing( packing
, format
, type
) )
806 convert
.index
|= CONVERT_PACKING_BIT
;
808 if ( width
!= destImageWidth
)
809 convert
.index
|= CONVERT_STRIDE_BIT
;
811 return gl_convert_texsubimage2d_tab
[mesaFormat
]( &convert
);
815 _mesa_convert_texsubimage3d( GLint mesaFormat
,
816 GLint xoffset
, GLint yoffset
, GLint zoffset
,
817 GLint width
, GLint height
, GLint depth
,
818 GLint dstImageWidth
, GLint dstImageHeight
,
819 GLenum format
, GLenum type
,
820 const struct gl_pixelstore_attrib
*packing
,
821 const GLvoid
*srcImage
, GLvoid
*dstImage
)
823 struct gl_texture_convert convert
;
829 ASSERT( mesaFormat
>= MESA_FORMAT_RGBA8888
);
830 ASSERT( mesaFormat
<= MESA_FORMAT_CI8
);
832 /* Make it easier to pass all the parameters around.
834 convert
.xoffset
= xoffset
;
835 convert
.yoffset
= yoffset
;
836 convert
.zoffset
= zoffset
;
837 convert
.width
= width
;
838 convert
.height
= height
;
839 convert
.depth
= depth
;
840 convert
.dstImageWidth
= dstImageWidth
;
841 convert
.dstImageHeight
= dstImageHeight
;
842 convert
.format
= format
;
844 convert
.packing
= packing
;
845 convert
.srcImage
= srcImage
;
846 convert
.dstImage
= dstImage
;
850 if ( convert_needs_packing( packing
, format
, type
) )
851 convert
.index
|= CONVERT_PACKING_BIT
;
853 if ( width
!= dstImageWidth
|| height
!= dstImageHeight
)
854 convert
.index
|= CONVERT_STRIDE_BIT
;
856 return gl_convert_texsubimage3d_tab
[mesaFormat
]( &convert
);
861 /* Nearest filtering only (for broken hardware that can't support
862 * all aspect ratios). This can be made a lot faster, but I don't
863 * really care enough...
865 void _mesa_rescale_teximage2d( const struct gl_texture_format
*texFormat
,
866 GLint srcWidth
, GLint srcHeight
,
867 GLint dstWidth
, GLint dstHeight
,
868 const GLvoid
*srcImage
, GLvoid
*dstImage
)
872 #define INNER_LOOP( HOP, WOP ) \
873 for ( row = 0 ; row < dstHeight ; row++ ) { \
874 GLint srcRow = row HOP hScale; \
875 for ( col = 0 ; col < dstWidth ; col++ ) { \
876 GLint srcCol = col WOP wScale; \
877 *dst++ = src[srcRow * srcWidth + srcCol]; \
881 #define RESCALE_IMAGE( TYPE ) \
883 const TYPE *src = (const TYPE *)srcImage; \
884 TYPE *dst = (TYPE *)dstImage; \
886 if ( srcHeight <= dstHeight ) { \
887 const GLint hScale = dstHeight / srcHeight; \
888 if ( srcWidth <= dstWidth ) { \
889 const GLint wScale = dstWidth / srcWidth; \
890 INNER_LOOP( /, / ); \
893 const GLint wScale = srcWidth / dstWidth; \
894 INNER_LOOP( /, * ); \
898 const GLint hScale = srcHeight / dstHeight; \
899 if ( srcWidth <= dstWidth ) { \
900 const GLint wScale = dstWidth / srcWidth; \
901 INNER_LOOP( *, / ); \
904 const GLint wScale = srcWidth / dstWidth; \
905 INNER_LOOP( *, * ); \
910 switch ( texFormat
->TexelBytes
) {
912 RESCALE_IMAGE( GLuint
);
916 RESCALE_IMAGE( GLushort
);
920 RESCALE_IMAGE( GLubyte
);