fix for gl_ztrick bug (Ove Kaaven)
[mesa.git] / src / mesa / main / texutil.c
1 /* $Id: texutil.c,v 1.16 2001/03/18 13:40:58 gareth Exp $ */
2
3 /*
4 * Mesa 3-D graphics library
5 * Version: 3.5
6 *
7 * Copyright (C) 1999-2001 Brian Paul All Rights Reserved.
8 *
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:
15 *
16 * The above copyright notice and this permission notice shall be included
17 * in all copies or substantial portions of the Software.
18 *
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.
25 *
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 */
29
30 #ifdef PC_HEADER
31 #include "all.h"
32 #else
33 #include "glheader.h"
34 #include "context.h"
35 #include "enums.h"
36 #include "image.h"
37 #include "macros.h"
38 #include "mem.h"
39 #include "mtypes.h"
40 #include "texformat.h"
41 #include "texutil.h"
42 #endif
43
44 #define DBG 0
45
46
47 struct gl_texture_convert {
48 GLint xoffset, yoffset, zoffset; /* Subimage offset */
49 GLint width, height, depth; /* Subimage region */
50
51 GLint imageWidth, imageHeight; /* Full image dimensions */
52 GLenum format, type;
53
54 const struct gl_pixelstore_attrib *packing;
55
56 const GLvoid *srcImage;
57 GLvoid *dstImage;
58
59 GLint index;
60 };
61
62 typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
63
64 #define CONVERT_STRIDE_BIT 0x1
65 #define CONVERT_PACKING_BIT 0x2
66
67
68
69 /* ================================================================
70 * RGBA8888 textures:
71 */
72
73 #define DST_TYPE GLuint
74 #define DST_TEXELS_PER_DWORD 1
75
76 #define CONVERT_TEXEL( src ) \
77 PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
78
79 #define CONVERT_DIRECT
80
81 #define SRC_TEXEL_BYTES 4
82
83 #define TAG(x) x##_rgba8888_direct
84 #define PRESERVE_DST_TYPE
85 #include "texutil_tmp.h"
86
87
88 #define CONVERT_TEXEL( src ) \
89 PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
90
91 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
92
93 #define SRC_TEXEL_BYTES 4
94
95 #define TAG(x) x##_abgr8888_to_rgba8888
96 #define PRESERVE_DST_TYPE
97 #include "texutil_tmp.h"
98
99
100 #define CONVERT_TEXEL( src ) \
101 PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
102
103 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
104
105 #define SRC_TEXEL_BYTES 3
106
107 #define TAG(x) x##_bgr888_to_rgba8888
108 #include "texutil_tmp.h"
109
110
111 #define CONVERT_RGBA8888( name ) \
112 static GLboolean \
113 convert_##name##_rgba8888( struct gl_texture_convert *convert ) \
114 { \
115 convert_func *tab; \
116 GLint index = convert->index; \
117 \
118 if ( convert->format == GL_ABGR_EXT && \
119 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
120 { \
121 tab = name##_tab_rgba8888_direct; \
122 } \
123 else if ( convert->format == GL_RGBA && \
124 ( convert->type == GL_UNSIGNED_BYTE || \
125 convert->type == GL_UNSIGNED_INT_8_8_8_8 ) ) \
126 { \
127 tab = name##_tab_abgr8888_to_rgba8888; \
128 } \
129 else if ( convert->format == GL_RGB && \
130 convert->type == GL_UNSIGNED_BYTE ) \
131 { \
132 tab = name##_tab_bgr888_to_rgba8888; \
133 } \
134 else \
135 { \
136 /* Can't handle this source format/type combination */ \
137 return GL_FALSE; \
138 } \
139 \
140 return tab[index]( convert ); \
141 }
142
143 CONVERT_RGBA8888( texsubimage2d )
144 CONVERT_RGBA8888( texsubimage3d )
145
146
147
148 /* ================================================================
149 * ARGB8888 textures:
150 */
151
152 #define DST_TYPE GLuint
153 #define DST_TEXELS_PER_DWORD 1
154
155 #define CONVERT_TEXEL( src ) \
156 PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
157
158 #define CONVERT_DIRECT
159
160 #define SRC_TEXEL_BYTES 4
161
162 #define TAG(x) x##_argb8888_direct
163 #define PRESERVE_DST_TYPE
164 #include "texutil_tmp.h"
165
166
167 #define CONVERT_TEXEL( src ) \
168 PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
169
170 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
171
172 #define SRC_TEXEL_BYTES 4
173
174 #define TAG(x) x##_abgr8888_to_argb8888
175 #define PRESERVE_DST_TYPE
176 #include "texutil_tmp.h"
177
178
179 #define CONVERT_TEXEL( src ) \
180 PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
181
182 #define CONVERT_TEXEL_DWORD( src ) CONVERT_TEXEL( src )
183
184 #define SRC_TEXEL_BYTES 3
185
186 #define TAG(x) x##_bgr888_to_argb8888
187 #include "texutil_tmp.h"
188
189
190 #define CONVERT_ARGB8888( name ) \
191 static GLboolean \
192 convert_##name##_argb8888( struct gl_texture_convert *convert ) \
193 { \
194 convert_func *tab; \
195 GLint index = convert->index; \
196 \
197 if ( convert->format == GL_BGRA && \
198 convert->type == GL_UNSIGNED_INT_8_8_8_8_REV ) \
199 { \
200 tab = name##_tab_argb8888_direct; \
201 } \
202 else if ( convert->format == GL_RGBA && \
203 convert->type == GL_UNSIGNED_BYTE ) \
204 { \
205 tab = name##_tab_abgr8888_to_argb8888; \
206 } \
207 else if ( convert->format == GL_RGB && \
208 convert->type == GL_UNSIGNED_BYTE ) \
209 { \
210 tab = name##_tab_bgr888_to_argb8888; \
211 } \
212 else \
213 { \
214 /* Can't handle this source format/type combination */ \
215 return GL_FALSE; \
216 } \
217 \
218 return tab[index]( convert ); \
219 }
220
221 CONVERT_ARGB8888( texsubimage2d )
222 CONVERT_ARGB8888( texsubimage3d )
223
224
225
226 /* ================================================================
227 * RGB888 textures:
228 */
229
230 static GLboolean
231 convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
232 {
233 /* This is a placeholder for now...
234 */
235 return GL_FALSE;
236 }
237
238 static GLboolean
239 convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
240 {
241 /* This is a placeholder for now...
242 */
243 return GL_FALSE;
244 }
245
246
247
248 /* ================================================================
249 * RGB565 textures:
250 */
251
252 #define DST_TYPE GLushort
253 #define DST_TEXELS_PER_DWORD 2
254
255 #define CONVERT_TEXEL( src ) \
256 PACK_COLOR_565( src[0], src[1], src[2] )
257
258 #define CONVERT_DIRECT
259
260 #define SRC_TEXEL_BYTES 2
261
262 #define TAG(x) x##_rgb565_direct
263 #define PRESERVE_DST_TYPE
264 #include "texutil_tmp.h"
265
266
267 #define CONVERT_TEXEL( src ) \
268 PACK_COLOR_565( src[0], src[1], src[2] )
269
270 #define CONVERT_TEXEL_DWORD( src ) \
271 ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
272 (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
273
274 #define SRC_TEXEL_BYTES 3
275
276 #define TAG(x) x##_bgr888_to_rgb565
277 #define PRESERVE_DST_TYPE
278 #include "texutil_tmp.h"
279
280
281 #define CONVERT_TEXEL( src ) \
282 PACK_COLOR_565( src[0], src[1], src[2] )
283
284 #define CONVERT_TEXEL_DWORD( src ) \
285 ((PACK_COLOR_565( src[0], src[1], src[2] )) | \
286 (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
287
288 #define SRC_TEXEL_BYTES 4
289
290 #define TAG(x) x##_abgr8888_to_rgb565
291 #include "texutil_tmp.h"
292
293
294 #define CONVERT_RGB565( name ) \
295 static GLboolean \
296 convert_##name##_rgb565( struct gl_texture_convert *convert ) \
297 { \
298 convert_func *tab; \
299 GLint index = convert->index; \
300 \
301 if ( convert->format == GL_RGB && \
302 convert->type == GL_UNSIGNED_SHORT_5_6_5 ) \
303 { \
304 tab = name##_tab_rgb565_direct; \
305 } \
306 else if ( convert->format == GL_RGB && \
307 convert->type == GL_UNSIGNED_BYTE ) \
308 { \
309 tab = name##_tab_bgr888_to_rgb565; \
310 } \
311 else if ( convert->format == GL_RGBA && \
312 convert->type == GL_UNSIGNED_BYTE ) \
313 { \
314 tab = name##_tab_abgr8888_to_rgb565; \
315 } \
316 else \
317 { \
318 /* Can't handle this source format/type combination */ \
319 return GL_FALSE; \
320 } \
321 \
322 return tab[index]( convert ); \
323 }
324
325 CONVERT_RGB565( texsubimage2d )
326 CONVERT_RGB565( texsubimage3d )
327
328
329
330 /* ================================================================
331 * ARGB4444 textures:
332 */
333
334 #define DST_TYPE GLushort
335 #define DST_TEXELS_PER_DWORD 2
336
337 #define CONVERT_TEXEL( src ) \
338 PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
339
340 #define CONVERT_DIRECT
341
342 #define SRC_TEXEL_BYTES 2
343
344 #define TAG(x) x##_argb4444_direct
345 #define PRESERVE_DST_TYPE
346 #include "texutil_tmp.h"
347
348
349 #define CONVERT_TEXEL( src ) \
350 PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
351
352 #define CONVERT_TEXEL_DWORD( src ) \
353 ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) | \
354 (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
355
356 #define SRC_TEXEL_BYTES 4
357
358 #define TAG(x) x##_rgba8888_to_argb4444
359 #include "texutil_tmp.h"
360
361
362 #define CONVERT_ARGB4444( name ) \
363 static GLboolean \
364 convert_##name##_argb4444( struct gl_texture_convert *convert ) \
365 { \
366 convert_func *tab; \
367 GLint index = convert->index; \
368 \
369 if ( convert->format == GL_BGRA && \
370 convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV ) \
371 { \
372 tab = name##_tab_argb4444_direct; \
373 } \
374 else if ( convert->format == GL_RGBA && \
375 convert->type == GL_UNSIGNED_BYTE ) \
376 { \
377 tab = name##_tab_rgba8888_to_argb4444; \
378 } \
379 else \
380 { \
381 /* Can't handle this source format/type combination */ \
382 return GL_FALSE; \
383 } \
384 \
385 return tab[index]( convert ); \
386 }
387
388 CONVERT_ARGB4444( texsubimage2d )
389 CONVERT_ARGB4444( texsubimage3d )
390
391
392
393 /* ================================================================
394 * ARGB1555 textures:
395 */
396
397 #define DST_TYPE GLushort
398 #define DST_TEXELS_PER_DWORD 2
399
400 #define CONVERT_TEXEL( src ) \
401 PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
402
403 #define CONVERT_DIRECT
404
405 #define SRC_TEXEL_BYTES 2
406
407 #define TAG(x) x##_argb1555_direct
408 #define PRESERVE_DST_TYPE
409 #include "texutil_tmp.h"
410
411
412 #define CONVERT_TEXEL( src ) \
413 PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
414
415 #define CONVERT_TEXEL_DWORD( src ) \
416 ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) | \
417 (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
418
419 #define SRC_TEXEL_BYTES 4
420
421 #define TAG(x) x##_rgba8888_to_argb1555
422 #include "texutil_tmp.h"
423
424
425 #define CONVERT_ARGB1555( name ) \
426 static GLboolean \
427 convert_##name##_argb1555( struct gl_texture_convert *convert ) \
428 { \
429 convert_func *tab; \
430 GLint index = convert->index; \
431 \
432 if ( convert->format == GL_BGRA && \
433 convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV ) \
434 { \
435 tab = name##_tab_argb1555_direct; \
436 } \
437 else if ( convert->format == GL_RGBA && \
438 convert->type == GL_UNSIGNED_BYTE ) \
439 { \
440 tab = name##_tab_rgba8888_to_argb1555; \
441 } \
442 else \
443 { \
444 /* Can't handle this source format/type combination */ \
445 return GL_FALSE; \
446 } \
447 \
448 return tab[index]( convert ); \
449 }
450
451 CONVERT_ARGB1555( texsubimage2d )
452 CONVERT_ARGB1555( texsubimage3d )
453
454
455
456 /* ================================================================
457 * AL88 textures:
458 */
459
460 #define DST_TYPE GLushort
461 #define DST_TEXELS_PER_DWORD 2
462
463 #define CONVERT_TEXEL( src ) \
464 PACK_COLOR_88( src[0], src[1] )
465
466 #define CONVERT_DIRECT
467
468 #define SRC_TEXEL_BYTES 2
469
470 #define TAG(x) x##_al88_direct
471 #define PRESERVE_DST_TYPE
472 #include "texutil_tmp.h"
473
474
475 #define CONVERT_TEXEL( src ) \
476 PACK_COLOR_88( src[0], 0x00 )
477
478 #define CONVERT_TEXEL_DWORD( src ) \
479 ((PACK_COLOR_88( src[0], 0x00 )) | \
480 (PACK_COLOR_88( src[1], 0x00 ) << 16))
481
482 #define SRC_TEXEL_BYTES 1
483
484 #define TAG(x) x##_a8_to_al88
485 #define PRESERVE_DST_TYPE
486 #include "texutil_tmp.h"
487
488
489 #define CONVERT_TEXEL( src ) \
490 PACK_COLOR_88( 0xff, src[0] )
491
492 #define CONVERT_TEXEL_DWORD( src ) \
493 ((PACK_COLOR_88( 0xff, src[0] )) | \
494 (PACK_COLOR_88( 0xff, src[1] ) << 16))
495
496 #define SRC_TEXEL_BYTES 1
497
498 #define TAG(x) x##_l8_to_al88
499 #include "texutil_tmp.h"
500
501
502 #define CONVERT_AL88( name ) \
503 static GLboolean \
504 convert_##name##_al88( struct gl_texture_convert *convert ) \
505 { \
506 convert_func *tab; \
507 GLint index = convert->index; \
508 \
509 if ( convert->format == GL_LUMINANCE_ALPHA && \
510 convert->type == GL_UNSIGNED_BYTE ) \
511 { \
512 tab = name##_tab_al88_direct; \
513 } \
514 else if ( convert->format == GL_ALPHA && \
515 convert->type == GL_UNSIGNED_BYTE ) \
516 { \
517 tab = name##_tab_a8_to_al88; \
518 } \
519 else if ( convert->format == GL_LUMINANCE && \
520 convert->type == GL_UNSIGNED_BYTE ) \
521 { \
522 tab = name##_tab_l8_to_al88; \
523 } \
524 else \
525 { \
526 /* Can't handle this source format/type combination */ \
527 return GL_FALSE; \
528 } \
529 \
530 return tab[index]( convert ); \
531 }
532
533 CONVERT_AL88( texsubimage2d )
534 CONVERT_AL88( texsubimage3d )
535
536
537
538 /* ================================================================
539 * RGB332 textures:
540 */
541
542 static GLboolean
543 convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
544 {
545 /* This is a placeholder for now...
546 */
547 return GL_FALSE;
548 }
549
550 static GLboolean
551 convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
552 {
553 /* This is a placeholder for now...
554 */
555 return GL_FALSE;
556 }
557
558
559
560 /* ================================================================
561 * CI8 (and all other single-byte texel) textures:
562 */
563
564 #define DST_TYPE GLubyte
565 #define DST_TEXELS_PER_DWORD 4
566
567 #define CONVERT_TEXEL( src ) src[0]
568
569 #define CONVERT_DIRECT
570
571 #define SRC_TEXEL_BYTES 1
572
573 #define TAG(x) x##_ci8_direct
574 #include "texutil_tmp.h"
575
576
577 #define CONVERT_CI8( name ) \
578 static GLboolean \
579 convert_##name##_ci8( struct gl_texture_convert *convert ) \
580 { \
581 convert_func *tab; \
582 GLint index = convert->index; \
583 \
584 if ( ( convert->format == GL_ALPHA || \
585 convert->format == GL_LUMINANCE || \
586 convert->format == GL_INTENSITY || \
587 convert->format == GL_COLOR_INDEX ) && \
588 convert->type == GL_UNSIGNED_BYTE ) \
589 { \
590 tab = name##_tab_ci8_direct; \
591 } \
592 else \
593 { \
594 /* Can't handle this source format/type combination */ \
595 return GL_FALSE; \
596 } \
597 \
598 return tab[index]( convert ); \
599 }
600
601 CONVERT_CI8( texsubimage2d )
602 CONVERT_CI8( texsubimage3d )
603
604
605
606 /* ================================================================
607 * Global entry points
608 */
609
610 static convert_func gl_convert_texsubimage2d_tab[] = {
611 convert_texsubimage2d_rgba8888,
612 convert_texsubimage2d_argb8888,
613 convert_texsubimage2d_rgb888,
614 convert_texsubimage2d_rgb565,
615 convert_texsubimage2d_argb4444,
616 convert_texsubimage2d_argb1555,
617 convert_texsubimage2d_al88,
618 convert_texsubimage2d_rgb332,
619 convert_texsubimage2d_ci8, /* These are all the same... */
620 convert_texsubimage2d_ci8,
621 convert_texsubimage2d_ci8,
622 convert_texsubimage2d_ci8,
623 };
624
625 static convert_func gl_convert_texsubimage3d_tab[] = {
626 convert_texsubimage3d_rgba8888,
627 convert_texsubimage3d_argb8888,
628 convert_texsubimage3d_rgb888,
629 convert_texsubimage3d_rgb565,
630 convert_texsubimage3d_argb4444,
631 convert_texsubimage3d_argb1555,
632 convert_texsubimage3d_al88,
633 convert_texsubimage3d_rgb332,
634 convert_texsubimage3d_ci8, /* These are all the same... */
635 convert_texsubimage3d_ci8,
636 convert_texsubimage3d_ci8,
637 convert_texsubimage3d_ci8,
638 };
639
640
641 /* See if we need to care about the pixel store attributes when we're
642 * converting the texture image. This should be stored as
643 * packing->_SomeBoolean and updated when the values change, to avoid
644 * testing every time...
645 */
646 static INLINE GLboolean
647 convert_needs_packing( const struct gl_pixelstore_attrib *packing,
648 GLenum format, GLenum type )
649 {
650 if ( ( packing->Alignment == 1 ||
651 ( packing->Alignment == 4 && /* Pick up the common Q3A case... */
652 format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
653 packing->RowLength == 0 &&
654 packing->SkipPixels == 0 &&
655 packing->SkipRows == 0 &&
656 packing->ImageHeight == 0 &&
657 packing->SkipImages == 0 &&
658 packing->SwapBytes == GL_FALSE &&
659 packing->LsbFirst == GL_FALSE ) {
660 return GL_FALSE;
661 } else {
662 return GL_TRUE;
663 }
664 }
665
666
667 GLboolean
668 _mesa_convert_texsubimage1d( GLint mesaFormat,
669 GLint xoffset,
670 GLint width,
671 GLenum format, GLenum type,
672 const struct gl_pixelstore_attrib *packing,
673 const GLvoid *srcImage, GLvoid *dstImage )
674 {
675 struct gl_texture_convert convert;
676
677 ASSERT( packing );
678 ASSERT( srcImage );
679 ASSERT( dstImage );
680
681 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
682 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
683
684 /* Make it easier to pass all the parameters around.
685 */
686 convert.xoffset = xoffset;
687 convert.yoffset = 0;
688 convert.width = width;
689 convert.height = 1;
690 convert.format = format;
691 convert.type = type;
692 convert.packing = packing;
693 convert.srcImage = srcImage;
694 convert.dstImage = dstImage;
695
696 convert.index = 0;
697
698 if ( convert_needs_packing( packing, format, type ) )
699 convert.index |= CONVERT_PACKING_BIT;
700
701 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
702 }
703
704 GLboolean
705 _mesa_convert_texsubimage2d( GLint mesaFormat,
706 GLint xoffset, GLint yoffset,
707 GLint width, GLint height,
708 GLint imageWidth,
709 GLenum format, GLenum type,
710 const struct gl_pixelstore_attrib *packing,
711 const GLvoid *srcImage, GLvoid *dstImage )
712 {
713 struct gl_texture_convert convert;
714
715 ASSERT( packing );
716 ASSERT( srcImage );
717 ASSERT( dstImage );
718
719 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
720 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
721
722 /* Make it easier to pass all the parameters around.
723 */
724 convert.xoffset = xoffset;
725 convert.yoffset = yoffset;
726 convert.width = width;
727 convert.height = height;
728 convert.imageWidth = imageWidth;
729 convert.format = format;
730 convert.type = type;
731 convert.packing = packing;
732 convert.srcImage = srcImage;
733 convert.dstImage = dstImage;
734
735 convert.index = 0;
736
737 if ( convert_needs_packing( packing, format, type ) )
738 convert.index |= CONVERT_PACKING_BIT;
739
740 if ( width != imageWidth )
741 convert.index |= CONVERT_STRIDE_BIT;
742
743 return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
744 }
745
746 GLboolean
747 _mesa_convert_texsubimage3d( GLint mesaFormat,
748 GLint xoffset, GLint yoffset, GLint zoffset,
749 GLint width, GLint height, GLint depth,
750 GLint imageWidth, GLint imageHeight,
751 GLenum format, GLenum type,
752 const struct gl_pixelstore_attrib *packing,
753 const GLvoid *srcImage, GLvoid *dstImage )
754 {
755 struct gl_texture_convert convert;
756
757 ASSERT( packing );
758 ASSERT( srcImage );
759 ASSERT( dstImage );
760
761 ASSERT( mesaFormat >= MESA_FORMAT_RGBA );
762 ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
763
764 /* Make it easier to pass all the parameters around.
765 */
766 convert.xoffset = xoffset;
767 convert.yoffset = yoffset;
768 convert.zoffset = zoffset;
769 convert.width = width;
770 convert.height = height;
771 convert.depth = depth;
772 convert.imageWidth = imageWidth;
773 convert.imageHeight = imageHeight;
774 convert.format = format;
775 convert.type = type;
776 convert.packing = packing;
777 convert.srcImage = srcImage;
778 convert.dstImage = dstImage;
779
780 convert.index = 0;
781
782 if ( convert_needs_packing( packing, format, type ) )
783 convert.index |= CONVERT_PACKING_BIT;
784
785 if ( width != imageWidth || height != imageHeight )
786 convert.index |= CONVERT_STRIDE_BIT;
787
788 return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
789 }
790
791
792
793 /* Nearest filtering only (for broken hardware that can't support
794 * all aspect ratios). This can be made a lot faster, but I don't
795 * really care enough...
796 */
797 void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
798 GLint srcWidth, GLint srcHeight,
799 GLint dstWidth, GLint dstHeight,
800 const GLvoid *srcImage, GLvoid *dstImage )
801 {
802 GLint row, col;
803
804 #define INNER_LOOP( HOP, WOP ) \
805 for ( row = 0 ; row < dstHeight ; row++ ) { \
806 GLint srcRow = row HOP hScale; \
807 for ( col = 0 ; col < dstWidth ; col++ ) { \
808 GLint srcCol = col WOP wScale; \
809 *dst++ = src[srcRow * srcWidth + srcCol]; \
810 } \
811 } \
812
813 #define RESCALE_IMAGE( TYPE ) \
814 do { \
815 const TYPE *src = (const TYPE *)srcImage; \
816 TYPE *dst = (TYPE *)dstImage; \
817 \
818 if ( srcHeight <= dstHeight ) { \
819 const GLint hScale = dstHeight / srcHeight; \
820 if ( srcWidth <= dstWidth ) { \
821 const GLint wScale = dstWidth / srcWidth; \
822 INNER_LOOP( /, / ); \
823 } \
824 else { \
825 const GLint wScale = srcWidth / dstWidth; \
826 INNER_LOOP( /, * ); \
827 } \
828 } \
829 else { \
830 const GLint hScale = srcHeight / dstHeight; \
831 if ( srcWidth <= dstWidth ) { \
832 const GLint wScale = dstWidth / srcWidth; \
833 INNER_LOOP( *, / ); \
834 } \
835 else { \
836 const GLint wScale = srcWidth / dstWidth; \
837 INNER_LOOP( *, * ); \
838 } \
839 } \
840 } while (0)
841
842 switch ( texFormat->TexelBytes ) {
843 case 4:
844 RESCALE_IMAGE( GLuint );
845 break;
846
847 case 2:
848 RESCALE_IMAGE( GLushort );
849 break;
850
851 case 1:
852 RESCALE_IMAGE( GLubyte );
853 break;
854 }
855 }