- Port 3.4 texture utils, texture format work to 3.5 (including new
authorGareth Hughes <gareth@valinux.com>
Sun, 18 Mar 2001 08:53:49 +0000 (08:53 +0000)
committerGareth Hughes <gareth@valinux.com>
Sun, 18 Mar 2001 08:53:49 +0000 (08:53 +0000)
  FetchTexel routines).
- Initial hooks for GL_EXT_texture_filter_anisotropic.

19 files changed:
src/mesa/Makefile.X11
src/mesa/main/Makefile.X11
src/mesa/main/attrib.c
src/mesa/main/config.h
src/mesa/main/context.c
src/mesa/main/extensions.c
src/mesa/main/get.c
src/mesa/main/macros.h
src/mesa/main/mtypes.h
src/mesa/main/texformat.c [new file with mode: 0644]
src/mesa/main/texformat.h [new file with mode: 0644]
src/mesa/main/texformat_tmp.h [new file with mode: 0644]
src/mesa/main/teximage.c
src/mesa/main/texobj.c
src/mesa/main/texstate.c
src/mesa/main/texstore.c
src/mesa/main/texutil.c
src/mesa/main/texutil.h
src/mesa/main/texutil_tmp.h [new file with mode: 0644]

index fdab3399ce3c28699345ef4f979a9ca2ebfa7b71..24109a739ce930f29f9959baed0af4d26978dea3 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.45 2001/02/16 18:14:41 keithw Exp $
+# $Id: Makefile.X11,v 1.46 2001/03/18 08:53:49 gareth Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -99,6 +99,7 @@ CORE_SOURCES = \
        scissor.c \
        state.c \
        stencil.c \
+       texformat.c \
        teximage.c \
        texobj.c \
        texstate.c \
index fdab3399ce3c28699345ef4f979a9ca2ebfa7b71..24109a739ce930f29f9959baed0af4d26978dea3 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: Makefile.X11,v 1.45 2001/02/16 18:14:41 keithw Exp $
+# $Id: Makefile.X11,v 1.46 2001/03/18 08:53:49 gareth Exp $
 
 # Mesa 3-D graphics library
 # Version:  3.5
@@ -99,6 +99,7 @@ CORE_SOURCES = \
        scissor.c \
        state.c \
        stencil.c \
+       texformat.c \
        teximage.c \
        texobj.c \
        texstate.c \
index 700106ea8f1e3a27c4d4bbdcf20813f3f09d10db..a26dcd2e3e98be2db6fc7af647b1701ab9885910 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: attrib.c,v 1.46 2001/03/12 00:48:37 gareth Exp $ */
+/* $Id: attrib.c,v 1.47 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -101,6 +101,7 @@ copy_texobj_state( struct gl_texture_object *dest,
    dest->MaxLod = src->MaxLod;
    dest->BaseLevel = src->BaseLevel;
    dest->MaxLevel = src->MaxLevel;
+   dest->MaxAnisotropy = src->MaxAnisotropy;
    dest->CompareFlag = src->CompareFlag;
    dest->CompareOperator = src->CompareOperator;
    dest->ShadowAmbient = src->ShadowAmbient;
index dff7c401380351756dc1574430aad7e319d6da61..c5392d724b38ba7c8420018c1140f27d12833e9b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: config.h,v 1.27 2001/03/12 00:48:37 gareth Exp $ */
+/* $Id: config.h,v 1.28 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
 /* GL_ARB_texture_compression */
 #define MAX_COMPRESSED_TEXTURE_FORMATS 25
 
+/* GL_EXT_texture_filter_anisotropic */
+#define MAX_TEXTURE_MAX_ANISOTROPY 16.0
+
 
 
 /*
index b732889cdf4ff838f1e5c97d212676fb67f9a8bf..013a16b95be75ad4f820c20de95ebb4430759bf0 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: context.c,v 1.128 2001/03/12 01:32:20 gareth Exp $ */
+/* $Id: context.c,v 1.129 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -721,6 +721,7 @@ init_attrib_groups( GLcontext *ctx )
    ctx->Const.MaxTextureSize = 1 << (MAX_TEXTURE_LEVELS - 1);
    ctx->Const.MaxCubeTextureSize = ctx->Const.MaxTextureSize;
    ctx->Const.MaxTextureUnits = MAX_TEXTURE_UNITS;
+   ctx->Const.MaxTextureMaxAnisotropy = MAX_TEXTURE_MAX_ANISOTROPY;
    ctx->Const.MaxArrayLockSize = MAX_ARRAY_LOCK_SIZE;
    ctx->Const.SubPixelBits = SUB_PIXEL_BITS;
    ctx->Const.MinPointSize = MIN_POINT_SIZE;
index 1b5c9cd448ed31c2f7eb04caabca72e90e339980..6a7d25fe2016dee59e6092ac17780a41296f57dd 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: extensions.c,v 1.52 2001/03/15 18:21:01 brianp Exp $ */
+/* $Id: extensions.c,v 1.53 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -56,59 +56,60 @@ static struct {
    const char *name;
    int flag_offset;
 } default_extensions[] = {
-   { OFF, "GL_ARB_imaging",                   F(ARB_imaging) },
-   { OFF, "GL_ARB_multitexture",              F(ARB_multitexture) },
-   { OFF, "GL_ARB_texture_compression",       F(ARB_texture_compression) },
-   { OFF, "GL_ARB_texture_cube_map",          F(ARB_texture_cube_map) },
-   { OFF, "GL_ARB_texture_env_add",           F(EXT_texture_env_add) },
-   { ON,  "GL_ARB_tranpose_matrix",           0 },
-   { ON,  "GL_EXT_abgr",                      0 },
-   { ON,  "GL_EXT_bgra",                      0 },
-   { OFF, "GL_EXT_blend_color",               F(EXT_blend_color) },
-   { OFF, "GL_EXT_blend_func_separate",       F(EXT_blend_func_separate) },
-   { OFF, "GL_EXT_blend_logic_op",            F(EXT_blend_logic_op) },
-   { OFF, "GL_EXT_blend_minmax",              F(EXT_blend_minmax) },
-   { OFF, "GL_EXT_blend_subtract",            F(EXT_blend_subtract) },
-   { ON,  "GL_EXT_clip_volume_hint",          F(EXT_clip_volume_hint) },
-   { OFF, "GL_EXT_cull_vertex",               0 },
-   { OFF, "GL_EXT_convolution",               F(EXT_convolution) },
-   { ON,  "GL_EXT_compiled_vertex_array",     F(EXT_compiled_vertex_array) },
-   { OFF, "GL_EXT_fog_coord",                 F(EXT_fog_coord) },
-   { OFF, "GL_EXT_histogram",                 F(EXT_histogram) },
-   { ON,  "GL_EXT_packed_pixels",             F(EXT_packed_pixels) },
-   { OFF, "GL_EXT_paletted_texture",          F(EXT_paletted_texture) },
-   { OFF, "GL_EXT_point_parameters",          F(EXT_point_parameters) },
-   { ON,  "GL_EXT_polygon_offset",            F(EXT_polygon_offset) },
-   { ON,  "GL_EXT_rescale_normal",            F(EXT_rescale_normal) },
-   { OFF, "GL_EXT_secondary_color",           F(EXT_secondary_color) },
-   { OFF, "GL_EXT_shared_texture_palette",    F(EXT_shared_texture_palette) },
-   { OFF, "GL_EXT_stencil_wrap",              F(EXT_stencil_wrap) },
-   { ON,  "GL_EXT_texture3D",                 F(EXT_texture3D) },
-   { OFF, "GL_EXT_texture_compression_s3tc",  F(EXT_texture_compression_s3tc)},
-   { OFF, "GL_EXT_texture_env_add",           F(EXT_texture_env_add) },
-   { OFF, "GL_EXT_texture_env_combine",       F(EXT_texture_env_combine) },
-   { OFF, "GL_EXT_texture_env_dot3",          F(EXT_texture_env_dot3) },
-   { ON,  "GL_EXT_texture_object",            F(EXT_texture_object) },
-   { OFF, "GL_EXT_texture_lod_bias",          F(EXT_texture_lod_bias) },
-   { ON,  "GL_EXT_vertex_array",              0 },
-   { OFF, "GL_EXT_vertex_array_set",          F(EXT_vertex_array_set) },
-   { OFF, "GL_HP_occlusion_test",             F(HP_occlusion_test) },
-   { OFF, "GL_INGR_blend_func_separate",      F(INGR_blend_func_separate) },
-   { OFF, "GL_MESA_packed_depth_stencil",     0 },
-   { OFF, "GL_MESA_resize_buffers",           F(MESA_resize_buffers) },
-   { OFF, "GL_MESA_sprite_point",             F(MESA_sprite_point) },
-   { ON,  "GL_MESA_window_pos",               F(MESA_window_pos) },
-   { OFF, "GL_NV_blend_square",               F(NV_blend_square) },
-   { ON,  "GL_NV_texgen_reflection",          F(NV_texgen_reflection) },
-   { OFF, "GL_SGI_color_matrix",              F(SGI_color_matrix) },
-   { OFF, "GL_SGI_color_table",               F(SGI_color_table) },
-   { OFF, "GL_SGIS_pixel_texture",            F(SGIS_pixel_texture) },
-   { OFF, "GL_SGIS_texture_edge_clamp",       F(SGIS_texture_edge_clamp) },
-   { OFF, "GL_SGIX_depth_texture",            F(SGIX_depth_texture) },
-   { OFF, "GL_SGIX_pixel_texture",            F(SGIX_pixel_texture) },
-   { OFF, "GL_SGIX_shadow",                   F(SGIX_shadow) },
-   { OFF, "GL_SGIX_shadow_ambient",           F(SGIX_shadow_ambient) },
-   { OFF, "GL_3DFX_texture_compression_FXT1", F(_3DFX_texture_compression_FXT1) }
+   { OFF, "GL_ARB_imaging",                    F(ARB_imaging) },
+   { OFF, "GL_ARB_multitexture",               F(ARB_multitexture) },
+   { OFF, "GL_ARB_texture_compression",        F(ARB_texture_compression) },
+   { OFF, "GL_ARB_texture_cube_map",           F(ARB_texture_cube_map) },
+   { OFF, "GL_ARB_texture_env_add",            F(EXT_texture_env_add) },
+   { ON,  "GL_ARB_tranpose_matrix",            0 },
+   { ON,  "GL_EXT_abgr",                       0 },
+   { ON,  "GL_EXT_bgra",                       0 },
+   { OFF, "GL_EXT_blend_color",                F(EXT_blend_color) },
+   { OFF, "GL_EXT_blend_func_separate",        F(EXT_blend_func_separate) },
+   { OFF, "GL_EXT_blend_logic_op",             F(EXT_blend_logic_op) },
+   { OFF, "GL_EXT_blend_minmax",               F(EXT_blend_minmax) },
+   { OFF, "GL_EXT_blend_subtract",             F(EXT_blend_subtract) },
+   { ON,  "GL_EXT_clip_volume_hint",           F(EXT_clip_volume_hint) },
+   { OFF, "GL_EXT_cull_vertex",                0 },
+   { OFF, "GL_EXT_convolution",                F(EXT_convolution) },
+   { ON,  "GL_EXT_compiled_vertex_array",      F(EXT_compiled_vertex_array) },
+   { OFF, "GL_EXT_fog_coord",                  F(EXT_fog_coord) },
+   { OFF, "GL_EXT_histogram",                  F(EXT_histogram) },
+   { ON,  "GL_EXT_packed_pixels",              F(EXT_packed_pixels) },
+   { OFF, "GL_EXT_paletted_texture",           F(EXT_paletted_texture) },
+   { OFF, "GL_EXT_point_parameters",           F(EXT_point_parameters) },
+   { ON,  "GL_EXT_polygon_offset",             F(EXT_polygon_offset) },
+   { ON,  "GL_EXT_rescale_normal",             F(EXT_rescale_normal) },
+   { OFF, "GL_EXT_secondary_color",            F(EXT_secondary_color) },
+   { OFF, "GL_EXT_shared_texture_palette",     F(EXT_shared_texture_palette) },
+   { OFF, "GL_EXT_stencil_wrap",               F(EXT_stencil_wrap) },
+   { ON,  "GL_EXT_texture3D",                  F(EXT_texture3D) },
+   { OFF, "GL_EXT_texture_compression_s3tc",   F(EXT_texture_compression_s3tc) },
+   { OFF, "GL_EXT_texture_env_add",            F(EXT_texture_env_add) },
+   { OFF, "GL_EXT_texture_env_combine",        F(EXT_texture_env_combine) },
+   { OFF, "GL_EXT_texture_env_dot3",           F(EXT_texture_env_dot3) },
+   { OFF, "GL_EXT_texture_filter_anisotropic", F(EXT_texture_filter_anisotropic) },
+   { ON,  "GL_EXT_texture_object",             F(EXT_texture_object) },
+   { OFF, "GL_EXT_texture_lod_bias",           F(EXT_texture_lod_bias) },
+   { ON,  "GL_EXT_vertex_array",               0 },
+   { OFF, "GL_EXT_vertex_array_set",           F(EXT_vertex_array_set) },
+   { OFF, "GL_HP_occlusion_test",              F(HP_occlusion_test) },
+   { OFF, "GL_INGR_blend_func_separate",       F(INGR_blend_func_separate) },
+   { OFF, "GL_MESA_packed_depth_stencil",      0 },
+   { OFF, "GL_MESA_resize_buffers",            F(MESA_resize_buffers) },
+   { OFF, "GL_MESA_sprite_point",              F(MESA_sprite_point) },
+   { ON,  "GL_MESA_window_pos",                F(MESA_window_pos) },
+   { OFF, "GL_NV_blend_square",                F(NV_blend_square) },
+   { ON,  "GL_NV_texgen_reflection",           F(NV_texgen_reflection) },
+   { OFF, "GL_SGI_color_matrix",               F(SGI_color_matrix) },
+   { OFF, "GL_SGI_color_table",                F(SGI_color_table) },
+   { OFF, "GL_SGIS_pixel_texture",             F(SGIS_pixel_texture) },
+   { OFF, "GL_SGIS_texture_edge_clamp",        F(SGIS_texture_edge_clamp) },
+   { OFF, "GL_SGIX_depth_texture",             F(SGIX_depth_texture) },
+   { OFF, "GL_SGIX_pixel_texture",             F(SGIX_pixel_texture) },
+   { OFF, "GL_SGIX_shadow",                    F(SGIX_shadow) },
+   { OFF, "GL_SGIX_shadow_ambient",            F(SGIX_shadow_ambient) },
+   { OFF, "GL_3DFX_texture_compression_FXT1",  F(_3DFX_texture_compression_FXT1) }
 };
 
 
index 83c4d16f3af622d56fdc33e97bb7d57a8c038852..c721bd4bfd9e5f3a5d6339d4a549b6a86c8fb85c 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: get.c,v 1.56 2001/03/12 00:48:37 gareth Exp $ */
+/* $Id: get.c,v 1.57 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -1253,6 +1253,17 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
         *params = INT_TO_BOOL(ctx->Array.FogCoord.Stride);
         break;
 
+      /* GL_EXT_texture_filter_anisotropic */
+      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+           *params = FLOAT_TO_BOOL(ctx->Const.MaxTextureMaxAnisotropy);
+         }
+         else {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glGetBooleanv" );
+            return;
+         }
+        break;
+
       /* GL_MESA_sprite_point */
       case GL_SPRITE_POINT_MESA:
          if (ctx->Extensions.MESA_sprite_point) {
@@ -2441,6 +2452,17 @@ _mesa_GetDoublev( GLenum pname, GLdouble *params )
         *params = (GLdouble) ctx->Array.FogCoord.Stride;
         break;
 
+      /* GL_EXT_texture_filter_anisotropic */
+      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+           *params = (GLdouble) ctx->Const.MaxTextureMaxAnisotropy;
+         }
+         else {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glGetDoublev" );
+            return;
+         }
+        break;
+
       /* GL_MESA_sprite_point */
       case GL_SPRITE_POINT_MESA:
          if (ctx->Extensions.MESA_sprite_point) {
@@ -3603,6 +3625,17 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
         *params = (GLfloat) ctx->Array.FogCoord.Stride;
         break;
 
+      /* GL_EXT_texture_filter_anisotropic */
+      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+           *params = ctx->Const.MaxTextureMaxAnisotropy;
+         }
+         else {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glGetFloatv" );
+            return;
+         }
+        break;
+
       /* GL_MESA_sprite_point */
       case GL_SPRITE_POINT_MESA:
          if (ctx->Extensions.MESA_sprite_point) {
@@ -4814,6 +4847,17 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
          }
         break;
 
+      /* GL_EXT_texture_filter_anisotropic */
+      case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+           *params = (GLint) ctx->Const.MaxTextureMaxAnisotropy;
+         }
+         else {
+            _mesa_error( ctx, GL_INVALID_ENUM, "glGetIntegerv" );
+            return;
+         }
+        break;
+
       /* GL_MESA_sprite_point */
       case GL_SPRITE_POINT_MESA:
          if (ctx->Extensions.MESA_sprite_point) {
index 1cfb55552d32a7057dc1caee3013733b629c6677..b9ccd906d4c2144b8e82fd890f300c3e6b7eb5b4 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: macros.h,v 1.19 2001/03/12 00:48:38 gareth Exp $ */
+/* $Id: macros.h,v 1.20 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -443,4 +443,31 @@ do {                                               \
 } while (0)
 
 
+
+/* Generic color packing macros
+ */
+
+#define PACK_COLOR_8888( a, b, c, d )                                  \
+   (((a) << 24) | ((b) << 16) | ((c) << 8) | (d))
+
+#define PACK_COLOR_888( a, b, c )                                      \
+   (((a) << 16) | ((b) << 8) | (c))
+
+#define PACK_COLOR_565( a, b, c )                                      \
+   ((((a) & 0xf8) << 8) | (((b) & 0xfc) << 3) | (((c) & 0xf8) >> 3))
+
+#define PACK_COLOR_1555( a, b, c, d )                                  \
+   ((((b) & 0xf8) << 7) | (((c) & 0xf8) << 2) | (((d) & 0xf8) >> 3) |  \
+    ((a) ? 0x8000 : 0))
+
+#define PACK_COLOR_4444( a, b, c, d )                                  \
+   ((((a) & 0xf0) << 8) | (((b) & 0xf0) << 4) | ((c) & 0xf0) | ((d) >> 4))
+
+#define PACK_COLOR_88( a, b )                                          \
+   (((a) << 8) | (b))
+
+#define PACK_COLOR_332( a, b, c )                                      \
+   (((a) & 0xe0) | (((b) & 0xe0) >> 3) | (((c) & 0xc0) >> 6))
+
+
 #endif
index f54b8d5fa9d59d269928e925e78b41e618300207..1ed5bad4c24f3c6d278f14e32749c7786d1c3b94 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: mtypes.h,v 1.26 2001/03/17 17:43:04 keithw Exp $ */
+/* $Id: mtypes.h,v 1.27 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -775,6 +775,25 @@ typedef void (*FetchTexelFunc)( const struct gl_texture_image *texImage,
                                 GLint col, GLint row, GLint img,
                                 GLvoid *texelOut );
 
+/* Texture format record */
+struct gl_texture_format {
+   GLint IntFormat;            /* One of the MESA_FORMAT_* values */
+
+   GLubyte RedBits;            /* Bits per texel component */
+   GLubyte GreenBits;
+   GLubyte BlueBits;
+   GLubyte AlphaBits;
+   GLubyte LuminanceBits;
+   GLubyte IntensityBits;
+   GLubyte IndexBits;
+   GLubyte DepthBits;
+
+   GLint TexelBytes;
+
+   FetchTexelFunc FetchTexel1D;        /* Texel fetch function pointers */
+   FetchTexelFunc FetchTexel2D;
+   FetchTexelFunc FetchTexel3D;
+};
 
 /* Texture image record */
 struct gl_texture_image {
@@ -784,14 +803,6 @@ struct gl_texture_image {
                                 */
    GLenum Type;                        /* Texel type: GL_UNSIGNED_BYTE, etc. */
    GLenum IntFormat;           /* Internal format as given by the user */
-   GLubyte RedBits;            /* Bits per texel component              */
-   GLubyte GreenBits;          /*   These are initialized by Mesa but   */
-   GLubyte BlueBits;           /*   may be reassigned by the device     */
-   GLubyte AlphaBits;          /*   driver to indicate the true texture */
-   GLubyte IntensityBits;      /*   color resolution.                   */
-   GLubyte LuminanceBits;
-   GLubyte IndexBits;
-   GLubyte DepthBits;
    GLuint Border;              /* 0 or 1 */
    GLuint Width;               /* = 2^WidthLog2 + 2*Border */
    GLuint Height;              /* = 2^HeightLog2 + 2*Border */
@@ -805,7 +816,9 @@ struct gl_texture_image {
    GLuint MaxLog2;             /* = MAX(WidthLog2, HeightLog2) */
    GLvoid *Data;               /* Image data, accessed via FetchTexel() */
 
-   FetchTexelFunc FetchTexel;  /* texel fetch function pointer */
+   const struct gl_texture_format *TexFormat;
+
+   FetchTexelFunc FetchTexel;  /* Texel fetch function pointer */
 
    GLboolean IsCompressed;     /* GL_ARB_texture_compression */
    GLuint CompressedSize;      /* GL_ARB_texture_compression */
@@ -832,6 +845,7 @@ struct gl_texture_object {
    GLfloat MaxLod;             /* max lambda, OpenGL 1.2 */
    GLint BaseLevel;            /* min mipmap level, OpenGL 1.2 */
    GLint MaxLevel;             /* max mipmap level, OpenGL 1.2 */
+   GLfloat MaxAnisotropy;      /* GL_EXT_texture_filter_anisotropic */
    GLboolean CompareFlag;      /* GL_SGIX_shadow */
    GLenum CompareOperator;     /* GL_SGIX_shadow */
    GLchan ShadowAmbient;       /* GL_SGIX_shadow_ambient */
@@ -1157,6 +1171,7 @@ struct gl_constants {
    GLint MaxCubeTextureSize;
    GLint MaxTextureLevels;
    GLuint MaxTextureUnits;
+   GLfloat MaxTextureMaxAnisotropy;    /* GL_EXT_texture_filter_anisotropic */
    GLuint MaxArrayLockSize;
    GLint SubPixelBits;
    GLfloat MinPointSize, MaxPointSize;         /* aliased */
@@ -1213,6 +1228,7 @@ struct gl_extensions {
    GLboolean EXT_texture_env_add;
    GLboolean EXT_texture_env_combine;
    GLboolean EXT_texture_env_dot3;
+   GLboolean EXT_texture_filter_anisotropic;
    GLboolean EXT_texture_object;
    GLboolean EXT_texture_lod_bias;
    GLboolean EXT_vertex_array_set;
diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c
new file mode 100644 (file)
index 0000000..d7b8024
--- /dev/null
@@ -0,0 +1,566 @@
+/* $Id: texformat.c,v 1.2 2001/03/18 08:53:49 gareth Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include "glheader.h"
+#include "colormac.h"
+#include "context.h"
+#include "image.h"
+#include "mem.h"
+#include "mmath.h"
+#include "mtypes.h"
+#include "texformat.h"
+#include "teximage.h"
+#include "texstate.h"
+#include "swrast/s_span.h"
+#endif
+
+
+/* Texel fetch routines for all supported formats:
+ */
+#define DIM 1
+#include "texformat_tmp.h"
+
+#define DIM 2
+#include "texformat_tmp.h"
+
+#define DIM 3
+#include "texformat_tmp.h"
+
+/* Have to have this so the FetchTexel function pointer is never NULL.
+ */
+static void fetch_null_texel( const struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = 0;
+   rgba[GCOMP] = 0;
+   rgba[BCOMP] = 0;
+   rgba[ACOMP] = 0;
+}
+
+
+/* ================================================================
+ * Default GLchan-based formats:
+ */
+
+const struct gl_texture_format _mesa_texformat_rgba = {
+   MESA_FORMAT_RGBA,                   /* IntFormat */
+   CHAN_BITS,                          /* RedBits */
+   CHAN_BITS,                          /* GreenBits */
+   CHAN_BITS,                          /* BlueBits */
+   CHAN_BITS,                          /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   4 * CHAN_BITS / 8,                  /* TexelBytes */
+   fetch_1d_texel_rgba,                        /* FetchTexel1D */
+   fetch_2d_texel_rgba,                        /* FetchTexel2D */
+   fetch_3d_texel_rgba,                        /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb = {
+   MESA_FORMAT_RGBA,                   /* IntFormat */
+   CHAN_BITS,                          /* RedBits */
+   CHAN_BITS,                          /* GreenBits */
+   CHAN_BITS,                          /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   3 * CHAN_BITS / 8,                  /* TexelBytes */
+   fetch_1d_texel_rgb,                 /* FetchTexel1D */
+   fetch_2d_texel_rgb,                 /* FetchTexel2D */
+   fetch_3d_texel_rgb,                 /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_alpha = {
+   MESA_FORMAT_ALPHA,                  /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   CHAN_BITS,                          /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   CHAN_BITS / 8,                      /* TexelBytes */
+   fetch_1d_texel_alpha,               /* FetchTexel1D */
+   fetch_2d_texel_alpha,               /* FetchTexel2D */
+   fetch_3d_texel_alpha,               /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance = {
+   MESA_FORMAT_LUMINANCE,              /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   CHAN_BITS,                          /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   CHAN_BITS / 8,                      /* TexelBytes */
+   fetch_1d_texel_luminance,           /* FetchTexel1D */
+   fetch_2d_texel_luminance,           /* FetchTexel2D */
+   fetch_3d_texel_luminance,           /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_luminance_alpha = {
+   MESA_FORMAT_LUMINANCE_ALPHA,                /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   CHAN_BITS,                          /* AlphaBits */
+   CHAN_BITS,                          /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   2 * CHAN_BITS / 8,                  /* TexelBytes */
+   fetch_1d_texel_luminance_alpha,     /* FetchTexel1D */
+   fetch_2d_texel_luminance_alpha,     /* FetchTexel2D */
+   fetch_3d_texel_luminance_alpha,     /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_intensity = {
+   MESA_FORMAT_INTENSITY,              /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   CHAN_BITS,                          /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   CHAN_BITS / 8,                      /* TexelBytes */
+   fetch_1d_texel_intensity,           /* FetchTexel1D */
+   fetch_2d_texel_intensity,           /* FetchTexel2D */
+   fetch_3d_texel_intensity,           /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_color_index = {
+   MESA_FORMAT_COLOR_INDEX,            /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   CHAN_BITS,                          /* IndexBits */
+   0,                                  /* DepthBits */
+   CHAN_BITS / 8,                      /* TexelBytes */
+   fetch_1d_texel_color_index,         /* FetchTexel1D */
+   fetch_2d_texel_color_index,         /* FetchTexel2D */
+   fetch_3d_texel_color_index,         /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_depth_component = {
+   MESA_FORMAT_DEPTH_COMPONENT,                /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   sizeof(GLfloat) * 8,                        /* DepthBits */
+   sizeof(GLfloat),                    /* TexelBytes */
+   fetch_1d_texel_depth_component,     /* FetchTexel1D */
+   fetch_2d_texel_depth_component,     /* FetchTexel2D */
+   fetch_3d_texel_depth_component,     /* FetchTexel3D */
+};
+
+
+/* ================================================================
+ * Hardware formats:
+ */
+
+const struct gl_texture_format _mesa_texformat_rgba8888 = {
+   MESA_FORMAT_RGBA8888,               /* IntFormat */
+   8,                                  /* RedBits */
+   8,                                  /* GreenBits */
+   8,                                  /* BlueBits */
+   8,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   4,                                  /* TexelBytes */
+   fetch_1d_texel_rgba8888,            /* FetchTexel1D */
+   fetch_2d_texel_rgba8888,            /* FetchTexel2D */
+   fetch_3d_texel_rgba8888,            /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_argb8888 = {
+   MESA_FORMAT_ARGB8888,               /* IntFormat */
+   8,                                  /* RedBits */
+   8,                                  /* GreenBits */
+   8,                                  /* BlueBits */
+   8,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   4,                                  /* TexelBytes */
+   fetch_1d_texel_argb8888,            /* FetchTexel1D */
+   fetch_2d_texel_argb8888,            /* FetchTexel2D */
+   fetch_3d_texel_argb8888,            /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb888 = {
+   MESA_FORMAT_RGB888,                 /* IntFormat */
+   8,                                  /* RedBits */
+   8,                                  /* GreenBits */
+   8,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   3,                                  /* TexelBytes */
+   fetch_1d_texel_rgb888,              /* FetchTexel1D */
+   fetch_2d_texel_rgb888,              /* FetchTexel2D */
+   fetch_3d_texel_rgb888,              /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb565 = {
+   MESA_FORMAT_RGB565,                 /* IntFormat */
+   5,                                  /* RedBits */
+   6,                                  /* GreenBits */
+   5,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   2,                                  /* TexelBytes */
+   fetch_1d_texel_rgb565,              /* FetchTexel1D */
+   fetch_2d_texel_rgb565,              /* FetchTexel2D */
+   fetch_3d_texel_rgb565,              /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_argb4444 = {
+   MESA_FORMAT_ARGB4444,               /* IntFormat */
+   4,                                  /* RedBits */
+   4,                                  /* GreenBits */
+   4,                                  /* BlueBits */
+   4,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   2,                                  /* TexelBytes */
+   fetch_1d_texel_argb4444,            /* FetchTexel1D */
+   fetch_2d_texel_argb4444,            /* FetchTexel2D */
+   fetch_3d_texel_argb4444,            /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_argb1555 = {
+   MESA_FORMAT_ARGB1555,               /* IntFormat */
+   5,                                  /* RedBits */
+   5,                                  /* GreenBits */
+   5,                                  /* BlueBits */
+   1,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   2,                                  /* TexelBytes */
+   fetch_1d_texel_argb1555,            /* FetchTexel1D */
+   fetch_2d_texel_argb1555,            /* FetchTexel2D */
+   fetch_3d_texel_argb1555,            /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_al88 = {
+   MESA_FORMAT_AL88,                   /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   8,                                  /* AlphaBits */
+   8,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   2,                                  /* TexelBytes */
+   fetch_1d_texel_al88,                        /* FetchTexel1D */
+   fetch_2d_texel_al88,                        /* FetchTexel2D */
+   fetch_3d_texel_al88,                        /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_rgb332 = {
+   MESA_FORMAT_RGB332,                 /* IntFormat */
+   3,                                  /* RedBits */
+   3,                                  /* GreenBits */
+   2,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   1,                                  /* TexelBytes */
+   fetch_1d_texel_rgb332,              /* FetchTexel1D */
+   fetch_2d_texel_rgb332,              /* FetchTexel2D */
+   fetch_3d_texel_rgb332,              /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_a8 = {
+   MESA_FORMAT_A8,                     /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   8,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   1,                                  /* TexelBytes */
+   fetch_1d_texel_a8,                  /* FetchTexel1D */
+   fetch_2d_texel_a8,                  /* FetchTexel2D */
+   fetch_3d_texel_a8,                  /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_l8 = {
+   MESA_FORMAT_L8,                     /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   8,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   1,                                  /* TexelBytes */
+   fetch_1d_texel_l8,                  /* FetchTexel1D */
+   fetch_2d_texel_l8,                  /* FetchTexel2D */
+   fetch_3d_texel_l8,                  /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_i8 = {
+   MESA_FORMAT_I8,                     /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   8,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   1,                                  /* TexelBytes */
+   fetch_1d_texel_i8,                  /* FetchTexel1D */
+   fetch_2d_texel_i8,                  /* FetchTexel2D */
+   fetch_3d_texel_i8,                  /* FetchTexel3D */
+};
+
+const struct gl_texture_format _mesa_texformat_ci8 = {
+   MESA_FORMAT_CI8,                    /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   8,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   1,                                  /* TexelBytes */
+   fetch_1d_texel_ci8,                 /* FetchTexel1D */
+   fetch_2d_texel_ci8,                 /* FetchTexel2D */
+   fetch_3d_texel_ci8,                 /* FetchTexel3D */
+};
+
+
+/* ================================================================
+ * Null format:
+ */
+
+const struct gl_texture_format _mesa_null_texformat = {
+   -1,                                 /* IntFormat */
+   0,                                  /* RedBits */
+   0,                                  /* GreenBits */
+   0,                                  /* BlueBits */
+   0,                                  /* AlphaBits */
+   0,                                  /* LuminanceBits */
+   0,                                  /* IntensityBits */
+   0,                                  /* IndexBits */
+   0,                                  /* DepthBits */
+   0,                                  /* TexelBytes */
+   fetch_null_texel,                   /* FetchTexel1D */
+   fetch_null_texel,                   /* FetchTexel2D */
+   fetch_null_texel,                   /* FetchTexel3D */
+};
+
+
+
+/*
+ * Given an internal texture format enum or 1, 2, 3, 4 return the
+ * corresponding _base_ internal format:  GL_ALPHA, GL_LUMINANCE,
+ * GL_LUMANCE_ALPHA, GL_INTENSITY, GL_RGB, or GL_RGBA.
+ * Return -1 if invalid enum.
+ */
+void _mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat,
+                           struct gl_texture_image *texImage )
+{
+   texImage->IntFormat = internalFormat;
+
+   /* Ask the driver for the base format, if it doesn't know, it will
+    * return -1;
+    */
+   if ( ctx->Driver.BaseCompressedTexFormat ) {
+      GLint format = 0;                        /* Silence compiler warning */
+      format = (*ctx->Driver.BaseCompressedTexFormat)( ctx, format );
+      if ( format >= 0 ) {
+        internalFormat = format;
+      }
+   }
+
+   switch ( internalFormat ) {
+      /* GH: Bias towards GL_RGB, GL_RGBA texture formats.  This has
+       * got to be better than sticking them way down the end of this
+       * huge list.
+       */
+   case 4:                             /* Quake3 uses this... */
+   case GL_RGBA:
+      texImage->Format = GL_RGBA;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_rgba;
+      break;
+
+   case 3:                             /* ... and this. */
+   case GL_RGB:
+      texImage->Format = GL_RGB;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_rgb;
+      break;
+
+      /* GH: Okay, keep checking as normal.  Still test for GL_RGB,
+       * GL_RGBA formats first.
+       */
+   case GL_RGBA2:
+   case GL_RGBA4:
+   case GL_RGB5_A1:
+   case GL_RGBA8:
+   case GL_RGB10_A2:
+   case GL_RGBA12:
+   case GL_RGBA16:
+      texImage->Format = GL_RGBA;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_rgba;
+      break;
+
+   case GL_R3_G3_B2:
+   case GL_RGB4:
+   case GL_RGB5:
+   case GL_RGB8:
+   case GL_RGB10:
+   case GL_RGB12:
+   case GL_RGB16:
+      texImage->Format = GL_RGB;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_rgb;
+      break;
+
+   case GL_ALPHA:
+   case GL_ALPHA4:
+   case GL_ALPHA8:
+   case GL_ALPHA12:
+   case GL_ALPHA16:
+      texImage->Format = GL_ALPHA;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_alpha;
+      break;
+
+   case 1:
+   case GL_LUMINANCE:
+   case GL_LUMINANCE4:
+   case GL_LUMINANCE8:
+   case GL_LUMINANCE12:
+   case GL_LUMINANCE16:
+      texImage->Format = GL_LUMINANCE;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_luminance;
+      break;
+
+   case 2:
+   case GL_LUMINANCE_ALPHA:
+   case GL_LUMINANCE4_ALPHA4:
+   case GL_LUMINANCE6_ALPHA2:
+   case GL_LUMINANCE8_ALPHA8:
+   case GL_LUMINANCE12_ALPHA4:
+   case GL_LUMINANCE12_ALPHA12:
+   case GL_LUMINANCE16_ALPHA16:
+      texImage->Format = GL_LUMINANCE_ALPHA;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_luminance_alpha;
+      break;
+
+   case GL_INTENSITY:
+   case GL_INTENSITY4:
+   case GL_INTENSITY8:
+   case GL_INTENSITY12:
+   case GL_INTENSITY16:
+      texImage->Format = GL_INTENSITY;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_intensity;
+      break;
+
+   case GL_COLOR_INDEX:
+   case GL_COLOR_INDEX1_EXT:
+   case GL_COLOR_INDEX2_EXT:
+   case GL_COLOR_INDEX4_EXT:
+   case GL_COLOR_INDEX8_EXT:
+   case GL_COLOR_INDEX12_EXT:
+   case GL_COLOR_INDEX16_EXT:
+      texImage->Format = GL_COLOR_INDEX;
+      texImage->Type = CHAN_TYPE;
+      texImage->TexFormat = &_mesa_texformat_color_index;
+      break;
+
+   case GL_DEPTH_COMPONENT:
+   case GL_DEPTH_COMPONENT16_SGIX:
+   case GL_DEPTH_COMPONENT24_SGIX:
+   case GL_DEPTH_COMPONENT32_SGIX:
+      if ( ctx->Extensions.SGIX_depth_texture ) {
+        texImage->Format = GL_DEPTH_COMPONENT;
+        texImage->Type = GL_FLOAT;     /* XXX or GL_UNSIGNED_INT? */
+        texImage->TexFormat = &_mesa_texformat_depth_component;
+      } else {
+        /* This error should have already been caught and dealt with.
+         */
+        _mesa_problem( ctx, "depth format without GL_SGIX_depth_texture" );
+      }
+      break;
+
+   default:
+      _mesa_problem( ctx, "unexpected format in _mesa_init_tex_format" );
+      return;
+   }
+}
diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h
new file mode 100644 (file)
index 0000000..c6b897f
--- /dev/null
@@ -0,0 +1,123 @@
+/* $Id: texformat.h,v 1.2 2001/03/18 08:53:49 gareth Exp $ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version:  3.5
+ *
+ * Copyright (C) 1999-2001  Brian Paul   All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Author:
+ *    Gareth Hughes <gareth@valinux.com>
+ */
+
+#ifndef TEXFORMAT_H
+#define TEXFORMAT_H
+
+#include "mtypes.h"
+
+
+/* The Mesa internal texture image types.  These will be set to their
+ * default value, but may be changed by drivers as required.
+ */
+enum _format {
+   /* Generic GLchan-based formats.  These are the default formats used
+    * by the software rasterizer and, unless the driver overrides the
+    * texture image functions, incoming images will be converted to one
+    * of these formats.  Components are arrays of GLchan values, so
+    * there will be no big/little endian issues.
+    *
+    * NOTE: Because these are based on the GLchan datatype, one cannot
+    * assume 8 bits per channel with these formats.  If you require
+    * GLubyte per channel, use one of the hardware formats below.
+    */
+   MESA_FORMAT_RGBA,
+   MESA_FORMAT_RGB,
+   MESA_FORMAT_ALPHA,
+   MESA_FORMAT_LUMINANCE,
+   MESA_FORMAT_LUMINANCE_ALPHA,
+   MESA_FORMAT_INTENSITY,
+   MESA_FORMAT_COLOR_INDEX,
+   MESA_FORMAT_DEPTH_COMPONENT,
+
+   /* Hardware-friendly formats.  Drivers can override the default
+    * formats and convert texture images to one of these as required.
+    * These formats are all little endian, as shown below.  They will be
+    * most useful for x86-based PC graphics card drivers.
+    *
+    * NOTE: In the default case, some of these formats will be
+    * duplicates of the default formats listed above.  However, these
+    * formats guarantee their internal component sizes, while GLchan may
+    * vary betwen GLubyte, GLushort and GLfloat.
+    */
+                               /* msb <------ TEXEL BITS -----------> lsb */
+                               /* ---- ---- ---- ---- ---- ---- ---- ---- */
+   MESA_FORMAT_RGBA8888,       /* RRRR RRRR GGGG GGGG BBBB BBBB AAAA AAAA */
+   MESA_FORMAT_ARGB8888,       /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
+   MESA_FORMAT_RGB888,         /*           RRRR RRRR GGGG GGGG BBBB BBBB */
+   MESA_FORMAT_RGB565,         /*                     RRRR RGGG GGGB BBBB */
+   MESA_FORMAT_ARGB4444,       /*                     AAAA RRRR GGGG BBBB */
+   MESA_FORMAT_ARGB1555,       /*                     ARRR RRGG GGGB BBBB */
+   MESA_FORMAT_AL88,           /*                     AAAA AAAA LLLL LLLL */
+   MESA_FORMAT_RGB332,         /*                               RRRG GGBB */
+   MESA_FORMAT_A8,             /*                               AAAA AAAA */
+   MESA_FORMAT_L8,             /*                               LLLL LLLL */
+   MESA_FORMAT_I8,             /*                               IIII IIII */
+   MESA_FORMAT_CI8             /*                               CCCC CCCC */
+};
+
+
+extern void
+_mesa_init_tex_format( GLcontext *ctx, GLenum internalFormat,
+                      struct gl_texture_image *texImage );
+
+
+/* The default formats, GLchan per component:
+ */
+extern const struct gl_texture_format _mesa_texformat_rgba;
+extern const struct gl_texture_format _mesa_texformat_rgb;
+extern const struct gl_texture_format _mesa_texformat_alpha;
+extern const struct gl_texture_format _mesa_texformat_luminance;
+extern const struct gl_texture_format _mesa_texformat_luminance_alpha;
+extern const struct gl_texture_format _mesa_texformat_intensity;
+extern const struct gl_texture_format _mesa_texformat_color_index;
+extern const struct gl_texture_format _mesa_texformat_depth_component;
+
+/* The hardware-friendly formats:
+ */
+extern const struct gl_texture_format _mesa_texformat_rgba8888;
+extern const struct gl_texture_format _mesa_texformat_abgr8888;
+extern const struct gl_texture_format _mesa_texformat_argb8888;
+extern const struct gl_texture_format _mesa_texformat_rgb888;
+extern const struct gl_texture_format _mesa_texformat_bgr888;
+extern const struct gl_texture_format _mesa_texformat_rgb565;
+extern const struct gl_texture_format _mesa_texformat_argb4444;
+extern const struct gl_texture_format _mesa_texformat_argb1555;
+extern const struct gl_texture_format _mesa_texformat_al88;
+extern const struct gl_texture_format _mesa_texformat_rgb332;
+extern const struct gl_texture_format _mesa_texformat_a8;
+extern const struct gl_texture_format _mesa_texformat_l8;
+extern const struct gl_texture_format _mesa_texformat_i8;
+extern const struct gl_texture_format _mesa_texformat_ci8;
+
+/* The null format:
+ */
+extern const struct gl_texture_format _mesa_null_texformat;
+
+#endif
diff --git a/src/mesa/main/texformat_tmp.h b/src/mesa/main/texformat_tmp.h
new file mode 100644 (file)
index 0000000..77084eb
--- /dev/null
@@ -0,0 +1,264 @@
+
+#if DIM == 1
+
+#define CHAN_SRC( t, i, j, k, sz )                                     \
+       ((GLchan *)(t)->Data + (i) * (sz))
+#define UBYTE_SRC( t, i, j, k, sz )                                    \
+       ((GLubyte *)(t)->Data + (i) * (sz))
+#define USHORT_SRC( t, i, j, k )                                       \
+       ((GLushort *)(t)->Data + (i))
+#define FLOAT_SRC( t, i, j, k )                                                \
+       ((GLfloat *)(t)->Data + (i))
+
+#define FETCH(x) fetch_1d_texel_##x
+
+#elif DIM == 2
+
+#define CHAN_SRC( t, i, j, k, sz )                                     \
+       ((GLchan *)(t)->Data + ((t)->Width * (j) + (i)) * (sz))
+#define UBYTE_SRC( t, i, j, k, sz )                                    \
+       ((GLubyte *)(t)->Data + ((t)->Width * (j) + (i)) * (sz))
+#define USHORT_SRC( t, i, j, k )                                       \
+       ((GLushort *)(t)->Data + ((t)->Width * (j) + (i)))
+#define FLOAT_SRC( t, i, j, k )                                                \
+       ((GLfloat *)(t)->Data + ((t)->Width * (j) + (i)))
+
+#define FETCH(x) fetch_2d_texel_##x
+
+#elif DIM == 3
+
+#define CHAN_SRC( t, i, j, k, sz )                                     \
+       (GLchan *)(t)->Data + (((t)->Height * (k) + (j)) *              \
+                               (t)->Width + (i)) * (sz)
+#define UBYTE_SRC( t, i, j, k, sz )                                    \
+       ((GLubyte *)(t)->Data + (((t)->Height * (k) + (j)) *            \
+                                (t)->Width + (i)) * (sz))
+#define USHORT_SRC( t, i, j, k )                                       \
+       ((GLushort *)(t)->Data + (((t)->Height * (k) + (j)) *           \
+                                 (t)->Width + (i)))
+#define FLOAT_SRC( t, i, j, k )                                                \
+       ((GLfloat *)(t)->Data + (((t)->Height * (k) + (j)) *            \
+                                 (t)->Width + (i)))
+
+#define FETCH(x) fetch_3d_texel_##x
+
+#else
+#error "..."
+#endif
+
+
+static void FETCH(rgba)( const struct gl_texture_image *texImage,
+                        GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 4 );
+   GLchan *rgba = (GLchan *) texel;
+   COPY_CHAN4( rgba, src );
+}
+
+static void FETCH(rgb)( const struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 3 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = src[0];
+   rgba[GCOMP] = src[1];
+   rgba[BCOMP] = src[2];
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(alpha)( const struct gl_texture_image *texImage,
+                         GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = 0;
+   rgba[GCOMP] = 0;
+   rgba[BCOMP] = 0;
+   rgba[ACOMP] = src[0];
+}
+
+static void FETCH(luminance)( const struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = src[0];
+   rgba[GCOMP] = src[0];
+   rgba[BCOMP] = src[0];
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(luminance_alpha)( const struct gl_texture_image *texImage,
+                                   GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 2 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = src[0];
+   rgba[GCOMP] = src[0];
+   rgba[BCOMP] = src[0];
+   rgba[ACOMP] = src[1];
+}
+
+static void FETCH(intensity)( const struct gl_texture_image *texImage,
+                             GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = src[0];
+   rgba[GCOMP] = src[0];
+   rgba[BCOMP] = src[0];
+   rgba[ACOMP] = src[0];
+}
+
+static void FETCH(color_index)( const struct gl_texture_image *texImage,
+                               GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLchan *src = CHAN_SRC( texImage, i, j, k, 1 );
+   GLchan *index = (GLchan *) texel;
+   *index = *src;
+}
+
+static void FETCH(depth_component)( const struct gl_texture_image *texImage,
+                                   GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLfloat *src = FLOAT_SRC( texImage, i, j, k );
+   GLfloat *depth = (GLfloat *) texel;
+   *depth = *src;
+}
+
+static void FETCH(rgba8888)( const struct gl_texture_image *texImage,
+                            GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 4 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[3] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[2] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[1] );
+   rgba[ACOMP] = UBYTE_TO_CHAN( src[0] );
+}
+
+static void FETCH(argb8888)( const struct gl_texture_image *texImage,
+                            GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 4 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[2] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[1] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[ACOMP] = UBYTE_TO_CHAN( src[3] );
+}
+
+static void FETCH(rgb888)( const struct gl_texture_image *texImage,
+                          GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 3 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[2] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[1] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(rgb565)( const struct gl_texture_image *texImage,
+                          GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLushort *src = USHORT_SRC( texImage, i, j, k );
+   GLchan *rgba = (GLchan *) texel; GLushort s = *src;
+   rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) * 255 / 0xf8 );
+   rgba[GCOMP] = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) * 255 / 0xfc );
+   rgba[BCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xf8) * 255 / 0xf8 );
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(argb4444)( const struct gl_texture_image *texImage,
+                            GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLushort *src = USHORT_SRC( texImage, i, j, k );
+   GLchan *rgba = (GLchan *) texel; GLushort s = *src;
+   rgba[RCOMP] = UBYTE_TO_CHAN( ((s >>  8) & 0xf) * 255 / 0xf );
+   rgba[GCOMP] = UBYTE_TO_CHAN( ((s >>  4) & 0xf) * 255 / 0xf );
+   rgba[BCOMP] = UBYTE_TO_CHAN( ((s      ) & 0xf) * 255 / 0xf );
+   rgba[ACOMP] = UBYTE_TO_CHAN( ((s >> 12) & 0xf) * 255 / 0xf );
+}
+
+static void FETCH(argb1555)( const struct gl_texture_image *texImage,
+                            GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLushort *src = USHORT_SRC( texImage, i, j, k );
+   GLchan *rgba = (GLchan *) texel; GLushort s = *src;
+   rgba[RCOMP] = UBYTE_TO_CHAN( ((s >> 10) & 0xf8) * 255 / 0xf8 );
+   rgba[GCOMP] = UBYTE_TO_CHAN( ((s >>  5) & 0xf8) * 255 / 0xf8 );
+   rgba[BCOMP] = UBYTE_TO_CHAN( ((s      ) & 0xf8) * 255 / 0xf8 );
+   rgba[ACOMP] = UBYTE_TO_CHAN( ((s >> 15) & 0x01) * 255 );
+}
+
+static void FETCH(al88)( const struct gl_texture_image *texImage,
+                        GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 2 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[ACOMP] = UBYTE_TO_CHAN( src[1] );
+}
+
+static void FETCH(rgb332)( const struct gl_texture_image *texImage,
+                          GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel; GLubyte s = *src;
+   rgba[RCOMP] = UBYTE_TO_CHAN( ((s     ) & 0xe0) * 255 / 0xe0 );
+   rgba[GCOMP] = UBYTE_TO_CHAN( ((s << 3) & 0xe0) * 255 / 0xe0 );
+   rgba[BCOMP] = UBYTE_TO_CHAN( ((s << 5) & 0xc0) * 255 / 0xc0 );
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(a8)( const struct gl_texture_image *texImage,
+                      GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = 0;
+   rgba[GCOMP] = 0;
+   rgba[BCOMP] = 0;
+   rgba[ACOMP] = UBYTE_TO_CHAN( src[0] );
+}
+
+static void FETCH(l8)( const struct gl_texture_image *texImage,
+                      GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[ACOMP] = CHAN_MAX;
+}
+
+static void FETCH(i8)( const struct gl_texture_image *texImage,
+                      GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 );
+   GLchan *rgba = (GLchan *) texel;
+   rgba[RCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[GCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[BCOMP] = UBYTE_TO_CHAN( src[0] );
+   rgba[ACOMP] = UBYTE_TO_CHAN( src[0] );
+}
+
+static void FETCH(ci8)( const struct gl_texture_image *texImage,
+                       GLint i, GLint j, GLint k, GLvoid *texel )
+{
+   const GLubyte *src = UBYTE_SRC( texImage, i, j, k, 1 );
+   GLchan *index = (GLchan *) texel;
+   *index = UBYTE_TO_CHAN( *src );
+}
+
+
+#undef CHAN_SRC
+#undef UBYTE_SRC
+#undef USHORT_SRC
+#undef FLOAT_SRC
+#undef FETCH
+#undef DIM
index 5a231d182dca6094ed403bfac3fadf730545e7f1..d44b5d6ee675cc97d88e2404882c0be8d46449f3 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: teximage.c,v 1.84 2001/03/12 00:48:38 gareth Exp $ */
+/* $Id: teximage.c,v 1.85 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -36,6 +36,7 @@
 #include "mem.h"
 #include "mmath.h"
 #include "state.h"
+#include "texformat.h"
 #include "teximage.h"
 #include "texstate.h"
 #include "mtypes.h"
@@ -559,13 +560,6 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->Format = 0;
    img->Type = 0;
    img->IntFormat = 0;
-   img->RedBits = 0;
-   img->GreenBits = 0;
-   img->BlueBits = 0;
-   img->AlphaBits = 0;
-   img->IntensityBits = 0;
-   img->LuminanceBits = 0;
-   img->IndexBits = 0;
    img->Border = 0;
    img->Width = 0;
    img->Height = 0;
@@ -577,9 +571,10 @@ clear_teximage_fields(struct gl_texture_image *img)
    img->HeightLog2 = 0;
    img->DepthLog2 = 0;
    img->Data = NULL;
+   img->TexFormat = &_mesa_null_texformat;
+   img->FetchTexel = NULL;
    img->IsCompressed = 0;
    img->CompressedSize = 0;
-   img->FetchTexel = NULL;
 }
 
 
@@ -1102,11 +1097,10 @@ void
 _mesa_GetTexImage( GLenum target, GLint level, GLenum format,
                    GLenum type, GLvoid *pixels )
 {
-   GET_CURRENT_CONTEXT(ctx);
    const struct gl_texture_unit *texUnit;
    const struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
@@ -1631,11 +1625,10 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
                      const GLvoid *pixels )
 {
    GLsizei postConvWidth = width;
-   GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (ctx->NewState & _NEW_PIXEL)
@@ -1675,11 +1668,10 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
                      const GLvoid *pixels )
 {
    GLsizei postConvWidth = width, postConvHeight = height;
-   GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (ctx->NewState & _NEW_PIXEL)
@@ -1720,11 +1712,10 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
                      GLenum format, GLenum type,
                      const GLvoid *pixels )
 {
-   GET_CURRENT_CONTEXT(ctx);
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-
+   GET_CURRENT_CONTEXT(ctx);
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (ctx->NewState & _NEW_PIXEL)
@@ -2247,7 +2238,6 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
-
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (subtexture_error_check(ctx, 1, target, level, xoffset, 0, 0,
@@ -2283,7 +2273,6 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
-
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (subtexture_error_check(ctx, 2, target, level, xoffset, yoffset, 0,
@@ -2319,7 +2308,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
-
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (subtexture_error_check(ctx, 3, target, level, xoffset, yoffset, zoffset,
@@ -2353,7 +2341,6 @@ _mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
    const struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
    GET_CURRENT_CONTEXT(ctx);
-
    ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
 
    if (level < 0 || level >= ctx->Const.MaxTextureLevels) {
index 0bcc0deae8b30adf0b93d79c06ea0835af10bcff..da4c636056367bbc05ac7a77d54a475a94ad080f 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texobj.c,v 1.44 2001/03/12 00:48:39 gareth Exp $ */
+/* $Id: texobj.c,v 1.45 2001/03/18 08:53:49 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -79,6 +79,7 @@ _mesa_alloc_texture_object( struct gl_shared_state *shared,
       obj->MaxLod = 1000.0;
       obj->BaseLevel = 0;
       obj->MaxLevel = 1000;
+      obj->MaxAnisotropy = 1.0;
       obj->CompareFlag = GL_FALSE;
       obj->CompareOperator = GL_TEXTURE_LEQUAL_R_SGIX;
       obj->ShadowAmbient = 0;
index d21503ac03e5231c6b20e002d74fbaa06cc31705..1a6a42a85c9623886361b7325390c058a668a927 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstate.c,v 1.36 2001/03/07 05:06:12 brianp Exp $ */
+/* $Id: texstate.c,v 1.37 2001/03/18 08:53:50 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -770,6 +770,19 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params )
          /* (keithh@netcomuk.co.uk) */
          texObj->Priority = CLAMP( params[0], 0.0F, 1.0F );
          break;
+      case GL_TEXTURE_MAX_ANISOTROPY_EXT:
+         if (ctx->Extensions.EXT_texture_filter_anisotropic) {
+           if (params[0] < 1.0) {
+              _mesa_error(ctx, GL_INVALID_VALUE, "glTexParameter(param)" );
+              return;
+           }
+            texObj->MaxAnisotropy = params[0];
+         }
+         else {
+            _mesa_error(ctx, GL_INVALID_ENUM, "glTexParameter(pname)");
+            return;
+         }
+         break;
       case GL_TEXTURE_COMPARE_SGIX:
          if (ctx->Extensions.SGIX_shadow) {
             texObj->CompareFlag = params[0] ? GL_TRUE : GL_FALSE;
@@ -923,32 +936,32 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
          *params = img->Border;
          return;
       case GL_TEXTURE_RED_SIZE:
-         *params = img->RedBits;
+         *params = img->TexFormat->RedBits;
          return;
       case GL_TEXTURE_GREEN_SIZE:
-         *params = img->GreenBits;
+         *params = img->TexFormat->GreenBits;
          return;
       case GL_TEXTURE_BLUE_SIZE:
-         *params = img->BlueBits;
+         *params = img->TexFormat->BlueBits;
          return;
       case GL_TEXTURE_ALPHA_SIZE:
-         *params = img->AlphaBits;
+         *params = img->TexFormat->AlphaBits;
          return;
       case GL_TEXTURE_INTENSITY_SIZE:
-         *params = img->IntensityBits;
+         *params = img->TexFormat->IntensityBits;
          return;
       case GL_TEXTURE_LUMINANCE_SIZE:
-         *params = img->LuminanceBits;
+         *params = img->TexFormat->LuminanceBits;
          return;
       case GL_TEXTURE_INDEX_SIZE_EXT:
-         *params = img->IndexBits;
+         *params = img->TexFormat->IndexBits;
          return;
       case GL_DEPTH_BITS:
          /* XXX this isn't in the GL_SGIX_depth_texture spec
           * but seems appropriate.
           */
          if (ctx->Extensions.SGIX_depth_texture)
-            *params = img->DepthBits;
+            *params = img->TexFormat->DepthBits;
          else
             _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(pname)");
          return;
index 3354f864070ba241d6c8732f054b06fe3a70c717..8fa9deb221851999c1316f11f236b9bf04e50241 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texstore.c,v 1.11 2001/03/12 00:48:39 gareth Exp $ */
+/* $Id: texstore.c,v 1.12 2001/03/18 08:53:50 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
@@ -50,6 +50,7 @@
 #include "swrast/s_span.h"
 
 
+#if 0
 /*
  * Default 1-D texture texel fetch function.  This will typically be
  * overridden by hardware drivers which store their texture images in
@@ -446,6 +447,7 @@ set_teximage_component_sizes( struct gl_texture_image *texImage )
          _mesa_problem(NULL, "unexpected format in set_teximage_component_sizes");
    }
 }
+#endif
 
 
 
@@ -793,8 +795,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   const GLint components = components_in_intformat(internalFormat);
-   GLint compSize;
    GLint postConvWidth = width;
 
    if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
@@ -802,20 +802,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
    }
 
    /* setup the teximage struct's fields */
-   texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
-   if (format == GL_DEPTH_COMPONENT) {
-      texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
-      compSize = sizeof(GLfloat);
-   }
-   else {
-      texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
-      compSize = sizeof(CHAN_TYPE);
-   }
-   texImage->FetchTexel = fetch_1d_texel;
-   set_teximage_component_sizes(texImage);
+   _mesa_init_tex_format( ctx, internalFormat, texImage );
+   texImage->FetchTexel = texImage->TexFormat->FetchTexel1D;
 
    /* allocate memory */
-   texImage->Data = (GLchan *) MALLOC(postConvWidth * components * compSize);
+   texImage->Data = (GLchan *) MALLOC(postConvWidth *
+                                     texImage->TexFormat->TexelBytes);
    if (!texImage->Data)
       return;      /* out of memory */
 
@@ -844,9 +836,8 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   const GLint components = components_in_intformat(internalFormat);
-   GLint compSize;
    GLint postConvWidth = width, postConvHeight = height;
+   GLint texelBytes;
 
    if (ctx->_ImageTransferState & IMAGE_CONVOLUTION_BIT) {
       _mesa_adjust_image_for_convolution(ctx, 2, &postConvWidth,
@@ -854,28 +845,21 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
    }
 
    /* setup the teximage struct's fields */
-   texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
-   if (format == GL_DEPTH_COMPONENT) {
-      texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
-      compSize = sizeof(GLfloat);
-   }
-   else {
-      texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
-      compSize = sizeof(CHAN_TYPE);
-   }
-   texImage->FetchTexel = fetch_2d_texel;
-   set_teximage_component_sizes(texImage);
+   _mesa_init_tex_format( ctx, internalFormat, texImage );
+   texImage->FetchTexel = texImage->TexFormat->FetchTexel2D;
+
+   texelBytes = texImage->TexFormat->TexelBytes;
 
    /* allocate memory */
-   texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight
-                                      * components * compSize);
+   texImage->Data = (GLchan *) MALLOC(postConvWidth * postConvHeight *
+                                      texelBytes);
    if (!texImage->Data)
       return;      /* out of memory */
 
    /* unpack image, apply transfer ops and store in texImage->Data */
    _mesa_transfer_teximage(ctx, 2, texImage->Format, (GLchan *) texImage->Data,
                            width, height, 1, 0, 0, 0,
-                           texImage->Width * components * sizeof(GLchan),
+                           texImage->Width * texelBytes,
                            0, /* dstImageStride */
                            format, type, pixels, packing);
 }
@@ -898,34 +882,24 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
                        struct gl_texture_object *texObj,
                        struct gl_texture_image *texImage)
 {
-   const GLint components = components_in_intformat(internalFormat);
-   GLint compSize;
+   GLint texelBytes;
 
    /* setup the teximage struct's fields */
-   texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
-   if (format == GL_DEPTH_COMPONENT) {
-      texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
-      compSize = sizeof(GLfloat);
-   }
-   else {
-      texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
-      compSize = sizeof(CHAN_TYPE);
-   }
-   texImage->FetchTexel = fetch_3d_texel;
-   set_teximage_component_sizes(texImage);
+   _mesa_init_tex_format( ctx, internalFormat, texImage );
+   texImage->FetchTexel = texImage->TexFormat->FetchTexel3D;
+
+   texelBytes = texImage->TexFormat->TexelBytes;
 
    /* allocate memory */
-   texImage->Data = (GLchan *) MALLOC(width * height * depth
-                                      * components * compSize);
+   texImage->Data = (GLchan *) MALLOC(width * height * depth * texelBytes);
    if (!texImage->Data)
       return;      /* out of memory */
 
    /* unpack image, apply transfer ops and store in texImage->Data */
    _mesa_transfer_teximage(ctx, 3, texImage->Format, (GLchan *) texImage->Data,
                            width, height, depth, 0, 0, 0,
-                           texImage->Width * components * sizeof(GLchan),
-                           texImage->Width * texImage->Height * components
-                           * sizeof(GLchan),
+                           texImage->Width * texelBytes,
+                           texImage->Width * texImage->Height * texelBytes,
                            format, type, pixels, packing);
 }
 
@@ -1422,7 +1396,6 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
    struct gl_texture_unit *texUnit;
    struct gl_texture_object *texObj;
    struct gl_texture_image *texImage;
-   GLint compSize;
 
    (void) format;
    (void) type;
@@ -1437,16 +1410,7 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level,
     * have to override this function.
     */
    /* setup the teximage struct's fields */
-   texImage->Format = (GLenum) _mesa_base_tex_format(ctx, internalFormat);
-   if (format == GL_DEPTH_COMPONENT) {
-      texImage->Type = GL_FLOAT; /* XXX or GL_UNSIGNED_INT? */
-      compSize = sizeof(GLfloat);
-   }
-   else {
-      texImage->Type = CHAN_TYPE; /* usually GL_UNSIGNED_BYTE */
-      compSize = sizeof(CHAN_TYPE);
-   }
-   set_teximage_component_sizes(texImage);
+   _mesa_init_tex_format( ctx, internalFormat, texImage );
 
    return GL_TRUE;
 }
index 345d431d6ecab9919f8e03f6ce78eefaa5de0262..dc963551ac1b176551645853bb69e8c2a17468b2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texutil.c,v 1.14 2001/03/12 00:48:39 gareth Exp $ */
+/* $Id: texutil.c,v 1.15 2001/03/18 08:53:50 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
-
 #ifdef PC_HEADER
 #include "all.h"
 #else
 #include "glheader.h"
 #include "context.h"
+#include "enums.h"
 #include "image.h"
+#include "macros.h"
 #include "mem.h"
-#include "texutil.h"
 #include "mtypes.h"
+#include "texformat.h"
+#include "texutil.h"
 #endif
 
+#define DBG 0
 
-/*
- * Texture utilities which may be useful to device drivers.
- * See the texutil.h for the list of supported internal formats.
- * It's expected that new formats will be added for new hardware.
+
+struct gl_texture_convert {
+   GLint xoffset, yoffset, zoffset;    /* Subimage offset */
+   GLint width, height, depth;         /* Subimage region */
+
+   GLint imageWidth, imageHeight;      /* Full image dimensions */
+   GLenum format, type;
+
+   const struct gl_pixelstore_attrib *packing;
+
+   const GLvoid *srcImage;
+   GLvoid *dstImage;
+
+   GLint index;
+};
+
+typedef GLboolean (*convert_func)( struct gl_texture_convert *convert );
+
+#define CONVERT_STRIDE_BIT     0x1
+#define CONVERT_PACKING_BIT    0x2
+
+
+
+/* ================================================================
+ * RGBA8888 textures:
  */
 
+#define DST_TYPE               GLuint
+#define DST_TEXELS_PER_DWORD   1
 
-/*
- * If the system is little endian and can do 4-byte word stores on
- * non 4-byte-aligned addresses then we can use this optimization.
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_rgba8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( src[0], src[1], src[2], src[3] )
+
+#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_abgr8888_to_rgba8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( src[0], src[1], src[2], 0xff )
+
+#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES                3
+
+#define TAG(x) x##_bgr888_to_rgba8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGBA8888( name )                                       \
+static GLboolean                                                       \
+convert_##name##_rgba8888( struct gl_texture_convert *convert )                \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_ABGR_EXT &&                              \
+       convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )                  \
+   {                                                                   \
+      tab = name##_tab_rgba8888_direct;                                        \
+   }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            ( convert->type == GL_UNSIGNED_BYTE ||                     \
+              convert->type == GL_UNSIGNED_INT_8_8_8_8 ) )             \
+   {                                                                   \
+      tab = name##_tab_abgr8888_to_rgba8888;                           \
+   }                                                                   \
+   else if ( convert->format == GL_RGB &&                              \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_bgr888_to_rgba8888;                             \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_RGBA8888( texsubimage2d )
+CONVERT_RGBA8888( texsubimage3d )
+
+
+
+/* ================================================================
+ * ARGB8888 textures:
  */
-#if defined(__i386__)
-#define DO_32BIT_STORES000
-#endif
 
+#define DST_TYPE               GLuint
+#define DST_TEXELS_PER_DWORD   1
 
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( src[3], src[2], src[1], src[0] )
 
-/*
- * Convert texture image data into one a specific internal format.
- * Input:
- *   dstFormat - the destination internal format
- *   dstWidth, dstHeight - the destination image size
- *   dstImage - pointer to destination image buffer
- *   dstRowStride - bytes to jump between image rows
- *   srcWidth, srcHeight - size of texture image
- *   srcFormat, srcType - format and datatype of source image
- *   srcImage - pointer to user's texture image
- *   packing - describes how user's texture image is packed.
- * Return: pointer to resulting image data or NULL if error or out of memory
- *   or NULL if we can't process the given image format/type/internalFormat
- *   combination.
- *
- * Supported type conversions:
- *   srcFormat           srcType                          dstFormat
- *   GL_INTENSITY        GL_UNSIGNED_BYTE                 MESA_I8
- *   GL_LUMINANCE        GL_UNSIGNED_BYTE                 MESA_L8
- *   GL_ALPHA            GL_UNSIGNED_BYTE                 MESA_A8
- *   GL_COLOR_INDEX      GL_UNSIGNED_BYTE                 MESA_C8
- *   GL_LUMINANCE_ALPHA  GL_UNSIGNED_BYTE                 MESA_A8_L8
- *   GL_RGB              GL_UNSIGNED_BYTE                 MESA_R5_G6_B5
- *   GL_RGB              GL_UNSIGNED_SHORT_5_6_5          MESA_R5_G6_B5
- *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A4_R4_G4_B4
- *   GL_BGRA             GL_UNSIGNED_SHORT_4_4_4_4_REV    MESA_A4_R4_G4_B4
- *   GL_BGRA             GL_UNSIGHED_SHORT_1_5_5_5_REV    MESA_A1_R5_G5_B5
- *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A1_R5_G5_B5
- *   GL_BGRA             GL_UNSIGNED_INT_8_8_8_8_REV      MESA_A8_R8_G8_B8
- *   GL_RGBA             GL_UNSIGNED_BYTE                 MESA_A8_R8_G8_B8
- *   GL_RGB              GL_UNSIGNED_BYTE                 MESA_A8_R8_G8_B8
- *   more to be added for new drivers...
- *
- * Notes:
- *   Some hardware only supports texture images of specific aspect ratios.
- *   This code will do power-of-two image up-scaling if that's needed.
- *
- *
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_argb8888_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_abgr8888_to_argb8888
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_8888( 0xff, src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )     CONVERT_TEXEL( src )
+
+#define SRC_TEXEL_BYTES                3
+
+#define TAG(x) x##_bgr888_to_argb8888
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB8888( name )                                       \
+static GLboolean                                                       \
+convert_##name##_argb8888( struct gl_texture_convert *convert )                \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_BGRA &&                                  \
+       convert->type == GL_UNSIGNED_INT_8_8_8_8_REV )                  \
+   {                                                                   \
+      tab = name##_tab_argb8888_direct;                                        \
+   }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_abgr8888_to_argb8888;                           \
+   }                                                                   \
+   else if ( convert->format == GL_RGB &&                              \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_bgr888_to_argb8888;                             \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_ARGB8888( texsubimage2d )
+CONVERT_ARGB8888( texsubimage3d )
+
+
+
+/* ================================================================
+ * RGB888 textures:
  */
-GLboolean
-_mesa_convert_teximage(MesaIntTexFormat dstFormat,
-                       GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
-                       GLint dstRowStride,
-                       GLint srcWidth, GLint srcHeight,
-                       GLenum srcFormat, GLenum srcType,
-                       const GLvoid *srcImage,
-                       const struct gl_pixelstore_attrib *packing)
+
+static GLboolean
+convert_texsubimage2d_rgb888( struct gl_texture_convert *convert )
 {
-   const GLint wScale = dstWidth / srcWidth;   /* must be power of two */
-   const GLint hScale = dstHeight / srcHeight; /* must be power of two */
-   ASSERT(dstWidth >= srcWidth);
-   ASSERT(dstHeight >= srcHeight);
-   ASSERT(dstImage);
-   ASSERT(srcImage);
-   ASSERT(packing);
-
-   switch (dstFormat) {
-      case MESA_I8:
-      case MESA_L8:
-      case MESA_A8:
-      case MESA_C8:
-         if (srcType != GL_UNSIGNED_BYTE ||
-             ((srcFormat != GL_INTENSITY) &&
-              (srcFormat != GL_LUMINANCE) &&
-              (srcFormat != GL_ALPHA) &&
-              (srcFormat != GL_COLOR_INDEX))) {
-            /* bad internal format / srcFormat combination */
-            return GL_FALSE;
-         }
-         else {
-            /* store as 8-bit texels */
-            if (wScale == 1 && hScale == 1) {
-               /* no scaling needed - fast case */
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLubyte *dst = (GLubyte *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  MEMCPY(dst, src, dstWidth * sizeof(GLubyte));
-                  dst += dstRowStride;
-                  src += srcStride;
-               }
-            }
-            else {
-               /* must rescale image */
-               GLubyte *dst = (GLubyte *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                             srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst += dstRowStride;
-               }
-            }
-         }
-         break;
-
-      case MESA_A8_L8:
-         if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
-            return GL_FALSE;
-         }
-         else {
-            /* store as 16-bit texels */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row, col;
-               for (row = 0; row < dstHeight; row++) {
-                  for (col = 0; col < dstWidth; col++) {
-                     GLubyte luminance = src[col * 2 + 0];
-                     GLubyte alpha = src[col * 2 + 1];
-                     dst[col] = ((GLushort) alpha << 8) | luminance;
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-                  src += srcStride;
-               }
-            }
-            else {
-               /* must rescale */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row, col;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint srcCol = col / wScale;
-                     GLubyte luminance = src[srcCol * 2 + 0];
-                     GLubyte alpha = src[srcCol * 2 + 1];
-                     dst[col] = ((GLushort) alpha << 8) | luminance;
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-                  src += srcStride;
-               }
-            }
-         }
-         break;
-
-      case MESA_R5_G6_B5:
-         if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  MEMCPY(dst, src, dstWidth * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col3;
-                  GLint halfDstWidth = dstWidth >> 1;
-                  for (col = col3 = 0; col < halfDstWidth; col++, col3 += 6) {
-                     GLubyte r0 = src[col3 + 0];
-                     GLubyte g0 = src[col3 + 1];
-                     GLubyte b0 = src[col3 + 2];
-                     GLubyte r1 = src[col3 + 3];
-                     GLubyte g1 = src[col3 + 4];
-                     GLubyte b1 = src[col3 + 5];
-                     GLuint d0 = ((r0 & 0xf8) << 8)
-                               | ((g0 & 0xfc) << 3)
-                               | ((b0 & 0xf8) >> 3);
-                     GLuint d1 = ((r1 & 0xf8) << 8)
-                               | ((g1 & 0xfc) << 3)
-                               | ((b1 & 0xf8) >> 3);
-                     dst[col] = (d1 << 16) | d0;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-#else /* 16-bit stores */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col3;
-                  for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-#endif
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col3 = (col / wScale) * 3;
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case (used by Quake3) */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
-               GLuint *dst = dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  GLint halfDstWidth = dstWidth >> 1;
-                  for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
-                     GLubyte r0 = src[col4 + 0];
-                     GLubyte g0 = src[col4 + 1];
-                     GLubyte b0 = src[col4 + 2];
-                     GLubyte r1 = src[col4 + 4];
-                     GLubyte g1 = src[col4 + 5];
-                     GLubyte b1 = src[col4 + 6];
-                     GLuint d0 = ((r0 & 0xf8) << 8)
-                               | ((g0 & 0xfc) << 3)
-                               | ((b0 & 0xf8) >> 3);
-                     GLuint d1 = ((r1 & 0xf8) << 8)
-                               | ((g1 & 0xfc) << 3)
-                               | ((b1 & 0xf8) >> 3);
-                     dst[col] = (d1 << 16) | d0;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-#else /* 16-bit stores */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-#endif
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this srcFormat/srcType combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A4_R4_G4_B4:
-         /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  MEMCPY(dst, src, dstWidth * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-#ifdef DO_32BIT_STORES
-               GLuint *dst = dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  GLint halfDstWidth = dstWidth >> 1;
-                  for (col = col4 = 0; col < halfDstWidth; col++, col4 += 8) {
-                     GLubyte r0 = src[col4 + 0];
-                     GLubyte g0 = src[col4 + 1];
-                     GLubyte b0 = src[col4 + 2];
-                     GLubyte a0 = src[col4 + 3];
-                     GLubyte r1 = src[col4 + 4];
-                     GLubyte g1 = src[col4 + 5];
-                     GLubyte b1 = src[col4 + 6];
-                     GLubyte a1 = src[col4 + 7];
-                     GLuint d0 = ((a0 & 0xf0) << 8)
-                               | ((r0 & 0xf0) << 4)
-                               | ((g0 & 0xf0)     )
-                               | ((b0 & 0xf0) >> 4);
-                     GLuint d1 = ((a1 & 0xf0) << 8)
-                               | ((r1 & 0xf0) << 4)
-                               | ((g1 & 0xf0)     )
-                               | ((b1 & 0xf0) >> 4);
-                     dst[col] = (d1 << 16) | d0;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-#else /* 16-bit stores */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0xf0) << 8)
-                              | ((r & 0xf0) << 4)
-                              | ((g & 0xf0)     )
-                              | ((b & 0xf0) >> 4);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-#endif
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0xf0) << 8)
-                              | ((r & 0xf0) << 4)
-                              | ((g & 0xf0)     )
-                              | ((b & 0xf0) >> 4);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this format/srcType combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A1_R5_G5_B5:
-         /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  MEMCPY(dst, src, dstWidth * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0x80) << 8)
-                              | ((r & 0xf8) << 7)
-                              | ((g & 0xf8) << 2)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0x80) << 8)
-                              | ((r & 0xf8) << 7)
-                              | ((g & 0xf8) << 2)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this source format/type combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A8_R8_G8_B8:
-      case MESA_FF_R8_G8_B8:
-         /* 32-bit texels */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV){
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  MEMCPY(dst, src, dstWidth * sizeof(GLuint));
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLuint *src = (const GLuint *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < dstWidth; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 srcWidth, srcFormat, srcType);
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint col, col3;
-                  for (col = col3 = 0; col < dstWidth; col++, col3 += 3) {
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     GLubyte a = 255;
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLuint *dst = (GLuint *) dstImage;
-               GLint row;
-               for (row = 0; row < dstHeight; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < dstWidth; col++) {
-                     GLint col3 = (col / wScale) * 3;
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     GLubyte a = 255;
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this source format/type combination */
-            return GL_FALSE;
-         }
-         if (dstFormat == MESA_FF_R8_G8_B8) {
-            /* set alpha bytes to 0xff */
-            GLint i;
-            GLubyte *dst = (GLubyte *) dstImage;
-            for (i = 0; i < dstWidth * dstHeight; i++) {
-               dst[i * 4 + 3] = 0xff;
-            }
-         }
-         break;
-
-      default:
-         /* unexpected internal format! */
-         return GL_FALSE;
-   }
-   return GL_TRUE;
+   /* This is a placeholder for now...
+    */
+   return GL_FALSE;
 }
 
+static GLboolean
+convert_texsubimage3d_rgb888( struct gl_texture_convert *convert )
+{
+   /* This is a placeholder for now...
+    */
+   return GL_FALSE;
+}
 
 
-/*
- * Replace a subregion of a texture image with new data.
- * Input:
- *   dstFormat - destination image format
- *   dstXoffset, dstYoffset - destination for new subregion (in texels)
- *   dstWidth, dstHeight - total size of dest image (in texels)
- *   dstImage - pointer to dest image
- *   dstRowStride - bytes to jump between image rows (in bytes)
- *   width, height - size of region to copy/replace (in texels)
- *   srcWidth, srcHeight - size of the corresponding gl_texture_image
- *   srcFormat, srcType - source image format and datatype
- *   srcImage - source image
- *   packing - source image packing information.
- * Return:  GL_TRUE or GL_FALSE for success, failure
- *
- * Notes:
- *   Like _mesa_convert_teximage(), we can do power-of-two image scaling
- *   to accomodate hardware with texture image aspect ratio constraints.
- *   dstWidth / srcWidth is used to compute the horizontal scaling factor and
- *   dstHeight / srcHeight is used to compute the vertical scaling factor.
+
+/* ================================================================
+ * RGB565 textures:
  */
-GLboolean
-_mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
-                          GLint dstXoffset, GLint dstYoffset,
-                          GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
-                          GLint dstRowStride,
-                          GLint width, GLint height,
-                          GLint srcWidth, GLint srcHeight,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcImage,
-                          const struct gl_pixelstore_attrib *packing)
-{
-   const GLint wScale = dstWidth / srcWidth;   /* must be power of two */
-   const GLint hScale = dstHeight / srcHeight; /* must be power of two */
-   ASSERT(dstWidth >= srcWidth);
-   ASSERT(dstHeight >= srcHeight);
-   ASSERT(dstImage);
-   ASSERT(srcImage);
-   ASSERT(packing);
-
-   width *= wScale;
-   height *= hScale;
-   dstXoffset *= wScale;
-   dstYoffset *= hScale;
-
-   /* XXX hscale != 1 and wscale != 1 not tested!!!! */
-
-   switch (dstFormat) {
-      case MESA_I8:
-      case MESA_L8:
-      case MESA_A8:
-      case MESA_C8:
-         if (srcType != GL_UNSIGNED_BYTE ||
-             ((srcFormat != GL_INTENSITY) &&
-              (srcFormat != GL_LUMINANCE) &&
-              (srcFormat != GL_ALPHA) &&
-              (srcFormat != GL_COLOR_INDEX))) {
-            /* bad internal format / srcFormat combination */
-            return GL_FALSE;
-         }
-         else {
-            /* store as 8-bit texels */
-            if (wScale == 1 && hScale == 1) {
-               /* no scaling needed - fast case */
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                  width, srcFormat, srcType);
-               GLubyte *dst = (GLubyte *) dstImage
-                            + dstYoffset * dstRowStride + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  MEMCPY(dst, src, width * sizeof(GLubyte));
-                  dst += dstRowStride;
-                  src += srcStride;
-               }
-            }
-            else {
-               /* must rescale image */
-               GLubyte *dst = (GLubyte *) dstImage
-                            + dstYoffset * dstRowStride + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst += dstRowStride;
-               }
-            }
-         }
-         break;
-
-      case MESA_A8_L8:
-         if (srcType != GL_UNSIGNED_BYTE || srcFormat != GL_LUMINANCE_ALPHA) {
-            return GL_FALSE;
-         }
-         else {
-            /* store as 16-bit texels */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row, col;
-               for (row = 0; row < height; row++) {
-                  for (col = 0; col < width; col++) {
-                     GLubyte luminance = src[col * 2 + 0];
-                     GLubyte alpha = src[col * 2 + 1];
-                     dst[col] = ((GLushort) alpha << 8) | luminance;
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-                  src += srcStride;
-               }
-            }
-            else {
-               /* must rescale */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row, col;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-                  for (col = 0; col < width; col++) {
-                     GLint srcCol = col / wScale;
-                     GLubyte luminance = src[srcCol * 2 + 0];
-                     GLubyte alpha = src[srcCol * 2 + 1];
-                     dst[col] = ((GLushort) alpha << 8) | luminance;
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-                  src += srcStride;
-               }
-            }
-         }
-         break;
-
-      case MESA_R5_G6_B5:
-         if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5) {
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  MEMCPY(dst, src, width * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGB && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint col, col3;
-                  for (col = col3 = 0; col < width; col++, col3 += 3) {
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     GLint col3 = (col / wScale) * 3;
-                     GLubyte r = src[col3 + 0];
-                     GLubyte g = src[col3 + 1];
-                     GLubyte b = src[col3 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case (used by Quake3) */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < width; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     dst[col] = ((r & 0xf8) << 8)
-                              | ((g & 0xfc) << 3)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this srcFormat/srcType combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A4_R4_G4_B4:
-         /* store as 16-bit texels (GR_TEXFMT_ARGB_4444) */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV){
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  MEMCPY(dst, src, width * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < width; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0xf0) << 8)
-                              | ((r & 0xf0) << 4)
-                              | ((g & 0xf0)     )
-                              | ((b & 0xf0) >> 4);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0xf0) << 8)
-                              | ((r & 0xf0) << 4)
-                              | ((g & 0xf0)     )
-                              | ((b & 0xf0) >> 4);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this format/srcType combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A1_R5_G5_B5:
-         /* store as 16-bit texels (GR_TEXFMT_ARGB_1555) */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV){
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  MEMCPY(dst, src, width * sizeof(GLushort));
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLushort *src = (const GLushort *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < width; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0x80) << 8)
-                              | ((r & 0xf8) << 7)
-                              | ((g & 0xf8) << 2)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  src += srcStride;
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLushort *dst = (GLushort *) ((GLubyte *) dstImage
-                             + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3];
-                     dst[col] = ((a & 0x80) << 8)
-                              | ((r & 0xf8) << 7)
-                              | ((g & 0xf8) << 2)
-                              | ((b & 0xf8) >> 3);
-                  }
-                  dst = (GLushort *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this source format/type combination */
-            return GL_FALSE;
-         }
-         break;
-
-      case MESA_A8_R8_G8_B8:
-      case MESA_FF_R8_G8_B8:
-         /* 32-bit texels */
-         if (srcFormat == GL_BGRA && srcType == GL_UNSIGNED_INT_8_8_8_8_REV) {
-            /* special, optimized case */
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLuint *dst = (GLuint *) ((GLubyte *) dstImage
-                           + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  MEMCPY(dst, src, width * sizeof(GLuint));
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLuint *dst = (GLuint *) ((GLubyte *) dstImage
-                           + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLuint *src = (const GLuint *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     dst[col] = src[col / wScale];
-                  }
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            if (dstFormat == MESA_FF_R8_G8_B8) {
-               /* set alpha bytes to 0xff */
-               GLint row, col;
-               GLubyte *dst = (GLubyte *) dstImage
-                              + dstYoffset * dstRowStride + dstXoffset * 4;
-               assert(wScale == 1 && hScale == 1); /* XXX not done */
-               for (row = 0; row < height; row++) {
-                  for (col = 0; col < width; col++) {
-                     dst[col * 4 + 3] = 0xff;
-                  }
-                  dst = dst + dstRowStride;
-               }
-            }
-         }
-         else if (srcFormat == GL_RGBA && srcType == GL_UNSIGNED_BYTE) {
-            /* general case */
-            const GLubyte aMask = (dstFormat==MESA_FF_R8_G8_B8) ? 0xff : 0x00;
-            if (wScale == 1 && hScale == 1) {
-               const GLubyte *src = (const GLubyte *)
-                  _mesa_image_address(packing, srcImage, srcWidth, srcHeight,
-                                      srcFormat, srcType, 0, 0, 0);
-               const GLint srcStride = _mesa_image_row_stride(packing,
-                                                 width, srcFormat, srcType);
-               GLuint *dst = (GLuint *) ((GLubyte *) dstImage
-                           + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint col, col4;
-                  for (col = col4 = 0; col < width; col++, col4 += 4) {
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3] | aMask;
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  src += srcStride;
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-            else {
-               /* must rescale image */
-               GLuint *dst = (GLuint *) ((GLubyte *) dstImage
-                           + dstYoffset * dstRowStride) + dstXoffset;
-               GLint row;
-               for (row = 0; row < height; row++) {
-                  GLint srcRow = row / hScale;
-                  const GLubyte *src = (const GLubyte *)
-                     _mesa_image_address(packing, srcImage, srcWidth,
-                                  srcHeight, srcFormat, srcType, 0, srcRow, 0);
-                  GLint col;
-                  for (col = 0; col < width; col++) {
-                     GLint col4 = (col / wScale) * 4;
-                     GLubyte r = src[col4 + 0];
-                     GLubyte g = src[col4 + 1];
-                     GLubyte b = src[col4 + 2];
-                     GLubyte a = src[col4 + 3] | aMask;
-                     dst[col] = (a << 24) | (r << 16) | (g << 8) | b;
-                  }
-                  dst = (GLuint *) ((GLubyte *) dst + dstRowStride);
-               }
-            }
-         }
-         else {
-            /* can't handle this source format/type combination */
-            return GL_FALSE;
-         }
-         break;
-
-
-      default:
-         /* unexpected internal format! */
-         return GL_FALSE;
-   }
-   return GL_TRUE;
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_rgb565_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_565( src[0], src[1], src[2] )) |           \
+                (PACK_COLOR_565( src[3], src[4], src[5] ) << 16))
+
+#define SRC_TEXEL_BYTES                3
+
+#define TAG(x) x##_bgr888_to_rgb565
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_565( src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_565( src[0], src[1], src[2] )) |           \
+                (PACK_COLOR_565( src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_abgr8888_to_rgb565
+#include "texutil_tmp.h"
+
+
+#define CONVERT_RGB565( name )                                         \
+static GLboolean                                                       \
+convert_##name##_rgb565( struct gl_texture_convert *convert )          \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_RGB &&                                   \
+       convert->type == GL_UNSIGNED_SHORT_5_6_5 )                      \
+   {                                                                   \
+      tab = name##_tab_rgb565_direct;                                  \
+   }                                                                   \
+   else if ( convert->format == GL_RGB &&                              \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_bgr888_to_rgb565;                               \
+   }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_abgr8888_to_rgb565;                             \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
 }
 
+CONVERT_RGB565( texsubimage2d )
+CONVERT_RGB565( texsubimage3d )
 
 
 
-/*
- * Used to convert 16-bit texels into GLubyte color components.
+/* ================================================================
+ * ARGB4444 textures:
+ */
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_argb4444_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_4444( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_4444( src[3], src[0], src[1], src[2] )) |  \
+                (PACK_COLOR_4444( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_rgba8888_to_argb4444
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB4444( name )                                       \
+static GLboolean                                                       \
+convert_##name##_argb4444( struct gl_texture_convert *convert )                \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_BGRA &&                                  \
+       convert->type == GL_UNSIGNED_SHORT_4_4_4_4_REV )                \
+   {                                                                   \
+      tab = name##_tab_argb4444_direct;                                        \
+   }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_rgba8888_to_argb4444;                           \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_ARGB4444( texsubimage2d )
+CONVERT_ARGB4444( texsubimage3d )
+
+
+
+/* ================================================================
+ * ARGB1555 textures:
+ */
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_argb1555_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_1555( src[3], src[0], src[1], src[2] )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_1555( src[3], src[0], src[1], src[2] )) |  \
+                (PACK_COLOR_1555( src[7], src[4], src[5], src[6] ) << 16))
+
+#define SRC_TEXEL_BYTES                4
+
+#define TAG(x) x##_rgba8888_to_argb1555
+#include "texutil_tmp.h"
+
+
+#define CONVERT_ARGB1555( name )                                       \
+static GLboolean                                                       \
+convert_##name##_argb1555( struct gl_texture_convert *convert )                \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_BGRA &&                                  \
+       convert->type == GL_UNSIGNED_SHORT_1_5_5_5_REV )                \
+   {                                                                   \
+      tab = name##_tab_argb1555_direct;                                        \
+   }                                                                   \
+   else if ( convert->format == GL_RGBA &&                             \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_rgba8888_to_argb1555;                           \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_ARGB1555( texsubimage2d )
+CONVERT_ARGB1555( texsubimage3d )
+
+
+
+/* ================================================================
+ * AL88 textures:
+ */
+
+#define DST_TYPE               GLushort
+#define DST_TEXELS_PER_DWORD   2
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_88( src[0], src[1] )
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                2
+
+#define TAG(x) x##_al88_direct
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_88( src[0], 0x00 )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_88( src[0], 0x00 )) |                      \
+                (PACK_COLOR_88( src[1], 0x00 ) << 16))
+
+#define SRC_TEXEL_BYTES                1
+
+#define TAG(x) x##_a8_to_al88
+#define PRESERVE_DST_TYPE
+#include "texutil_tmp.h"
+
+
+#define CONVERT_TEXEL( src )                                           \
+               PACK_COLOR_88( 0xff, src[0] )
+
+#define CONVERT_TEXEL_DWORD( src )                                     \
+               ((PACK_COLOR_88( 0xff, src[0] )) |                      \
+                (PACK_COLOR_88( 0xff, src[1] ) << 16))
+
+#define SRC_TEXEL_BYTES                1
+
+#define TAG(x) x##_l8_to_al88
+#include "texutil_tmp.h"
+
+
+#define CONVERT_AL88( name )                                           \
+static GLboolean                                                       \
+convert_##name##_al88( struct gl_texture_convert *convert )            \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( convert->format == GL_LUMINANCE_ALPHA &&                       \
+       convert->type == GL_UNSIGNED_BYTE )                             \
+   {                                                                   \
+      tab = name##_tab_al88_direct;                                    \
+   }                                                                   \
+   else if ( convert->format == GL_ALPHA &&                            \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_a8_to_al88;                                     \
+   }                                                                   \
+   else if ( convert->format == GL_LUMINANCE &&                                \
+            convert->type == GL_UNSIGNED_BYTE )                        \
+   {                                                                   \
+      tab = name##_tab_l8_to_al88;                                     \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
+}
+
+CONVERT_AL88( texsubimage2d )
+CONVERT_AL88( texsubimage3d )
+
+
+
+/* ================================================================
+ * RGB332 textures:
  */
-static GLubyte R5G6B5toRed[0xffff];
-static GLubyte R5G6B5toGreen[0xffff];
-static GLubyte R5G6B5toBlue[0xffff];
-
-static GLubyte A4R4G4B4toRed[0xffff];
-static GLubyte A4R4G4B4toGreen[0xffff];
-static GLubyte A4R4G4B4toBlue[0xffff];
-static GLubyte A4R4G4B4toAlpha[0xffff];
-
-static GLubyte A1R5G5B5toRed[0xffff];
-static GLubyte A1R5G5B5toGreen[0xffff];
-static GLubyte A1R5G5B5toBlue[0xffff];
-static GLubyte A1R5G5B5toAlpha[0xffff];
-
-static void
-generate_lookup_tables(void)
+
+static GLboolean
+convert_texsubimage2d_rgb332( struct gl_texture_convert *convert )
 {
-   GLint i;
-   for (i = 0; i <= 0xffff; i++) {
-      GLint r = (i >> 8) & 0xf8;
-      GLint g = (i >> 3) & 0xfc;
-      GLint b = (i << 3) & 0xf8;
-      r = r * 255 / 0xf8;
-      g = g * 255 / 0xfc;
-      b = b * 255 / 0xf8;
-      R5G6B5toRed[i]   = r;
-      R5G6B5toGreen[i] = g;
-      R5G6B5toBlue[i]  = b;
-   }
+   /* This is a placeholder for now...
+    */
+   return GL_FALSE;
+}
 
-   for (i = 0; i <= 0xffff; i++) {
-      GLint r = (i >>  8) & 0xf;
-      GLint g = (i >>  4) & 0xf;
-      GLint b = (i      ) & 0xf;
-      GLint a = (i >> 12) & 0xf;
-      r = r * 255 / 0xf;
-      g = g * 255 / 0xf;
-      b = b * 255 / 0xf;
-      a = a * 255 / 0xf;
-      A4R4G4B4toRed[i]   = r;
-      A4R4G4B4toGreen[i] = g;
-      A4R4G4B4toBlue[i]  = b;
-      A4R4G4B4toAlpha[i] = a;
-   }
+static GLboolean
+convert_texsubimage3d_rgb332( struct gl_texture_convert *convert )
+{
+   /* This is a placeholder for now...
+    */
+   return GL_FALSE;
+}
 
-   for (i = 0; i <= 0xffff; i++) {
-      GLint r = (i >> 10) & 0xf8;
-      GLint g = (i >>  5) & 0xf8;
-      GLint b = (i      ) & 0xf8;
-      GLint a = (i >> 15) & 0x1;
-      r = r * 255 / 0xf8;
-      g = g * 255 / 0xf8;
-      b = b * 255 / 0xf8;
-      a = a * 255;
-      A1R5G5B5toRed[i]   = r;
-      A1R5G5B5toGreen[i] = g;
-      A1R5G5B5toBlue[i]  = b;
-      A1R5G5B5toAlpha[i] = a;
-   }
+
+
+/* ================================================================
+ * CI8 (and all other single-byte texel) textures:
+ */
+
+#define DST_TYPE               GLubyte
+#define DST_TEXELS_PER_DWORD   4
+
+#define CONVERT_TEXEL( src )   src[0]
+
+#define CONVERT_DIRECT
+
+#define SRC_TEXEL_BYTES                1
+
+#define TAG(x) x##_ci8_direct
+#include "texutil_tmp.h"
+
+
+#define CONVERT_CI8( name )                                            \
+static GLboolean                                                       \
+convert_##name##_ci8( struct gl_texture_convert *convert )             \
+{                                                                      \
+   convert_func *tab;                                                  \
+   GLint index = convert->index;                                       \
+                                                                       \
+   if ( ( convert->format == GL_ALPHA ||                               \
+         convert->format == GL_LUMINANCE ||                            \
+         convert->format == GL_INTENSITY ||                            \
+         convert->format == GL_COLOR_INDEX ) &&                        \
+       convert->type == GL_UNSIGNED_BYTE )                             \
+   {                                                                   \
+      tab = name##_tab_ci8_direct;                                     \
+   }                                                                   \
+   else                                                                        \
+   {                                                                   \
+      /* Can't handle this source format/type combination */           \
+      return GL_FALSE;                                                 \
+   }                                                                   \
+                                                                       \
+   return tab[index]( convert );                                       \
 }
 
+CONVERT_CI8( texsubimage2d )
+CONVERT_CI8( texsubimage3d )
 
 
-/*
- * Convert a texture image from an internal format to one of Mesa's
- * core internal formats.  This is likely to be used by glGetTexImage
- * and for fetching texture images when falling back to software rendering.
- *
- * Input:
- *   srcFormat - source image format
- *   srcWidth, srcHeight - source image size
- *   srcImage - source image pointer
- *   srcRowStride - bytes to jump between image rows
- *   dstWidth, dstHeight - size of dest image
- *   dstFormat - format of dest image (must be one of Mesa's IntFormat values)
- *   dstImage - pointer to dest image
- * Notes:
- *   This function will do power of two image down-scaling to accomodate
- *   drivers with limited texture image aspect ratios.
- *   The implicit dest data type is GL_UNSIGNED_BYTE.
+
+/* ================================================================
+ * Global entry points
  */
-void
-_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
-                         GLint srcWidth, GLint srcHeight,
-                         const GLvoid *srcImage, GLint srcRowStride,
-                         GLint dstWidth, GLint dstHeight,
-                         GLenum dstFormat, GLubyte *dstImage)
+
+static convert_func gl_convert_texsubimage2d_tab[] = {
+   convert_texsubimage2d_rgba8888,
+   convert_texsubimage2d_argb8888,
+   convert_texsubimage2d_rgb888,
+   convert_texsubimage2d_rgb565,
+   convert_texsubimage2d_argb4444,
+   convert_texsubimage2d_argb1555,
+   convert_texsubimage2d_al88,
+   convert_texsubimage2d_rgb332,
+   convert_texsubimage2d_ci8,          /* These are all the same... */
+   convert_texsubimage2d_ci8,
+   convert_texsubimage2d_ci8,
+   convert_texsubimage2d_ci8,
+};
+
+static convert_func gl_convert_texsubimage3d_tab[] = {
+   convert_texsubimage3d_rgba8888,
+   convert_texsubimage3d_argb8888,
+   convert_texsubimage3d_rgb888,
+   convert_texsubimage3d_rgb565,
+   convert_texsubimage3d_argb4444,
+   convert_texsubimage3d_argb1555,
+   convert_texsubimage3d_al88,
+   convert_texsubimage3d_rgb332,
+   convert_texsubimage3d_ci8,          /* These are all the same... */
+   convert_texsubimage3d_ci8,
+   convert_texsubimage3d_ci8,
+   convert_texsubimage3d_ci8,
+};
+
+
+/* See if we need to care about the pixel store attributes when we're
+ * converting the texture image.  This should be stored as
+ * packing->_SomeBoolean and updated when the values change, to avoid
+ * testing every time...
+ */
+static INLINE GLboolean
+convert_needs_packing( const struct gl_pixelstore_attrib *packing,
+                      GLenum format, GLenum type )
 {
-   static GLboolean firstCall = GL_TRUE;
-   const GLint wScale = srcWidth / dstWidth;   /* must be power of two */
-   const GLint hScale = srcHeight / dstHeight; /* must be power of two */
-   ASSERT(srcWidth >= dstWidth);
-   ASSERT(srcHeight >= dstHeight);
-   ASSERT(dstImage);
-   ASSERT(srcImage);
-
-   if (firstCall) {
-      generate_lookup_tables();
-      firstCall = GL_FALSE;
+   if ( ( packing->Alignment == 1 ||
+         ( packing->Alignment == 4 &&  /* Pick up the common Q3A case... */
+           format == GL_RGBA && type == GL_UNSIGNED_BYTE ) ) &&
+       packing->RowLength == 0 &&
+       packing->SkipPixels == 0 &&
+       packing->SkipRows == 0 &&
+       packing->ImageHeight == 0 &&
+       packing->SkipImages == 0 &&
+       packing->SwapBytes == GL_FALSE &&
+       packing->LsbFirst == GL_FALSE ) {
+      return GL_FALSE;
+   } else {
+      return GL_TRUE;
    }
+}
 
-   switch (srcFormat) {
-      case MESA_I8:
-      case MESA_L8:
-      case MESA_A8:
-      case MESA_C8:
-#ifdef DEBUG
-         if (srcFormat == MESA_I8) {
-            ASSERT(dstFormat == GL_INTENSITY);
-         }
-         else if (srcFormat == MESA_L8) {
-            ASSERT(dstFormat == GL_LUMINANCE);
-         }
-         else if (srcFormat == MESA_A8) {
-            ASSERT(dstFormat == GL_ALPHA);
-         }
-         else if (srcFormat == MESA_C8) {
-            ASSERT(dstFormat == GL_COLOR_INDEX);
-         }
-#endif
-         if (wScale == 1 && hScale == 1) {
-            /* easy! */
-            MEMCPY(dstImage, srcImage, dstWidth * dstHeight * sizeof(GLubyte));
-         }
-         else {
-            /* rescale */
-            const GLubyte *src8 = (const GLubyte *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  *dstImage++ = src8[srcRow * srcWidth + srcCol];
-               }
-            }
-         }
-         break;
-      case MESA_A8_L8:
-         ASSERT(dstFormat == GL_LUMINANCE_ALPHA);
-         if (wScale == 1 && hScale == 1) {
-            GLint i, n = dstWidth * dstHeight;
-            const GLushort *texel = (const GLushort *) srcImage;
-            for (i = 0; i < n; i++) {
-               const GLushort tex = *texel++;
-               *dstImage++ = (tex & 0xff); /* luminance */
-               *dstImage++ = (tex >> 8);   /* alpha */
-            }
-         }
-         else {
-            /* rescale */
-            const GLushort *src16 = (const GLushort *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
-                  *dstImage++ = (tex & 0xff); /* luminance */
-                  *dstImage++ = (tex >> 8);   /* alpha */
-               }
-            }
-         }
-         break;
-      case MESA_R5_G6_B5:
-         ASSERT(dstFormat == GL_RGB);
-         if (wScale == 1 && hScale == 1) {
-            GLint i, n = dstWidth * dstHeight;
-            const GLushort *texel = (const GLushort *) srcImage;
-            for (i = 0; i < n; i++) {
-               const GLushort tex = *texel++;
-               *dstImage++ = R5G6B5toRed[tex];
-               *dstImage++ = R5G6B5toGreen[tex];
-               *dstImage++ = R5G6B5toBlue[tex];
-            }
-         }
-         else {
-            /* rescale */
-            const GLushort *src16 = (const GLushort *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
-                  *dstImage++ = R5G6B5toRed[tex];
-                  *dstImage++ = R5G6B5toGreen[tex];
-                  *dstImage++ = R5G6B5toBlue[tex];
-               }
-            }
-         }
-         break;
-      case MESA_A4_R4_G4_B4:
-         ASSERT(dstFormat == GL_RGBA);
-         if (wScale == 1 && hScale == 1) {
-            GLint i, n = dstWidth * dstHeight;
-            const GLushort *texel = (const GLushort *) srcImage;
-            for (i = 0; i < n; i++) {
-               const GLushort tex = *texel++;
-               *dstImage++ = A4R4G4B4toRed[tex];
-               *dstImage++ = A4R4G4B4toGreen[tex];
-               *dstImage++ = A4R4G4B4toBlue[tex];
-               *dstImage++ = A4R4G4B4toAlpha[tex];
-            }
-         }
-         else {
-            /* rescale */
-            const GLushort *src16 = (const GLushort *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
-                  *dstImage++ = A4R4G4B4toRed[tex];
-                  *dstImage++ = A4R4G4B4toGreen[tex];
-                  *dstImage++ = A4R4G4B4toBlue[tex];
-                  *dstImage++ = A4R4G4B4toAlpha[tex];
-               }
-            }
-         }
-         break;
-      case MESA_A1_R5_G5_B5:
-         ASSERT(dstFormat == GL_RGBA);
-         if (wScale == 1 && hScale == 1) {
-            GLint i, n = dstWidth * dstHeight;
-            const GLushort *texel = (const GLushort *) srcImage;
-            for (i = 0; i < n; i++) {
-               const GLushort tex = *texel++;
-               *dstImage++ = A1R5G5B5toRed[tex];
-               *dstImage++ = A1R5G5B5toGreen[tex];
-               *dstImage++ = A1R5G5B5toBlue[tex];
-               *dstImage++ = A1R5G5B5toAlpha[tex];
-            }
-         }
-         else {
-            /* rescale */
-            const GLushort *src16 = (const GLushort *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  const GLushort tex = src16[srcRow * srcWidth + srcCol];
-                  *dstImage++ = A1R5G5B5toRed[tex];
-                  *dstImage++ = A1R5G5B5toGreen[tex];
-                  *dstImage++ = A1R5G5B5toBlue[tex];
-                  *dstImage++ = A1R5G5B5toAlpha[tex];
-               }
-            }
-         }
-         break;
-      case MESA_A8_R8_G8_B8:
-      case MESA_FF_R8_G8_B8:
-         ASSERT(dstFormat == GL_RGBA);
-         if (wScale == 1 && hScale == 1) {
-            GLint i, n = dstWidth * dstHeight;
-            const GLuint *texel = (const GLuint *) srcImage;
-            for (i = 0; i < n; i++) {
-               const GLuint tex = *texel++;
-               *dstImage++ = (tex >> 16) & 0xff; /* R */
-               *dstImage++ = (tex >>  8) & 0xff; /* G */
-               *dstImage++ = (tex      ) & 0xff; /* B */
-               *dstImage++ = (tex >> 24) & 0xff; /* A */
-            }
-         }
-         else {
-            /* rescale */
-            const GLuint *src = (const GLuint *) srcImage;
-            GLint row, col;
-            for (row = 0; row < dstHeight; row++) {
-               GLint srcRow = row * hScale;
-               for (col = 0; col < dstWidth; col++) {
-                  GLint srcCol = col * wScale;
-                  const GLuint tex = src[srcRow * srcWidth + srcCol];
-                  *dstImage++ = (tex >> 16) & 0xff; /* R */
-                  *dstImage++ = (tex >>  8) & 0xff; /* G */
-                  *dstImage++ = (tex      ) & 0xff; /* B */
-                  *dstImage++ = (tex >> 24) & 0xff; /* A */
-               }
-            }
-         }
-         break;
-      default:
-         _mesa_problem(NULL, "bad srcFormat in _mesa_uncovert_teximage()");
-   }
+
+GLboolean
+_mesa_convert_texsubimage1d( GLint mesaFormat,
+                            GLint xoffset,
+                            GLint width,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage )
+{
+   struct gl_texture_convert convert;
+
+   ASSERT( packing );
+   ASSERT( srcImage );
+   ASSERT( dstImage );
+
+   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+   /* Make it easier to pass all the parameters around.
+    */
+   convert.xoffset = xoffset;
+   convert.yoffset = 0;
+   convert.width = width;
+   convert.height = 1;
+   convert.format = format;
+   convert.type = type;
+   convert.packing = packing;
+   convert.srcImage = srcImage;
+   convert.dstImage = dstImage;
+
+   convert.index = 0;
+
+   if ( convert_needs_packing( packing, format, type ) )
+      convert.index |= CONVERT_PACKING_BIT;
+
+   return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
 }
 
+GLboolean
+_mesa_convert_texsubimage2d( GLint mesaFormat,
+                            GLint xoffset, GLint yoffset,
+                            GLint width, GLint height,
+                            GLint imageWidth,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage )
+{
+   struct gl_texture_convert convert;
 
+   ASSERT( packing );
+   ASSERT( srcImage );
+   ASSERT( dstImage );
 
-/*
- * Given an internal Mesa driver texture format, fill in the component
- * bit sizes in the given texture image struct.
+   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+   /* Make it easier to pass all the parameters around.
+    */
+   convert.xoffset = xoffset;
+   convert.yoffset = yoffset;
+   convert.width = width;
+   convert.height = height;
+   convert.imageWidth = imageWidth;
+   convert.format = format;
+   convert.type = type;
+   convert.packing = packing;
+   convert.srcImage = srcImage;
+   convert.dstImage = dstImage;
+
+   convert.index = 0;
+
+   if ( convert_needs_packing( packing, format, type ) )
+      convert.index |= CONVERT_PACKING_BIT;
+
+   if ( width != imageWidth )
+      convert.index |= CONVERT_STRIDE_BIT;
+
+   return gl_convert_texsubimage2d_tab[mesaFormat]( &convert );
+}
+
+GLboolean
+_mesa_convert_texsubimage3d( GLint mesaFormat,
+                            GLint xoffset, GLint yoffset, GLint zoffset,
+                            GLint width, GLint height, GLint depth,
+                            GLint imageWidth, GLint imageHeight,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage )
+{
+   struct gl_texture_convert convert;
+
+   ASSERT( packing );
+   ASSERT( srcImage );
+   ASSERT( dstImage );
+
+   ASSERT( mesaFormat >= MESA_FORMAT_RGBA8888 );
+   ASSERT( mesaFormat <= MESA_FORMAT_CI8 );
+
+   /* Make it easier to pass all the parameters around.
+    */
+   convert.xoffset = xoffset;
+   convert.yoffset = yoffset;
+   convert.zoffset = zoffset;
+   convert.width = width;
+   convert.height = height;
+   convert.depth = depth;
+   convert.imageWidth = imageWidth;
+   convert.imageHeight = imageHeight;
+   convert.format = format;
+   convert.type = type;
+   convert.packing = packing;
+   convert.srcImage = srcImage;
+   convert.dstImage = dstImage;
+
+   convert.index = 0;
+
+   if ( convert_needs_packing( packing, format, type ) )
+      convert.index |= CONVERT_PACKING_BIT;
+
+   if ( width != imageWidth || height != imageHeight )
+      convert.index |= CONVERT_STRIDE_BIT;
+
+   return gl_convert_texsubimage3d_tab[mesaFormat]( &convert );
+}
+
+
+
+/* Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios).  This can be made a lot faster, but I don't
+ * really care enough...
  */
-void
-_mesa_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
-                                   struct gl_texture_image *texImage)
+void _mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+                              GLint srcWidth, GLint srcHeight,
+                              GLint dstWidth, GLint dstHeight,
+                              const GLvoid *srcImage, GLvoid *dstImage )
 {
-   static const GLint bitSizes [][8] = {
-      /* format            R  G  B  A  I  L  C */
-      { MESA_I8,           0, 0, 0, 0, 8, 0, 0 },
-      { MESA_L8,           0, 0, 0, 0, 0, 8, 0 },
-      { MESA_A8,           0, 0, 0, 8, 0, 0, 0 },
-      { MESA_C8,           0, 0, 0, 0, 0, 0, 8 },
-      { MESA_A8_L8,        0, 0, 0, 8, 0, 8, 0 },
-      { MESA_R5_G6_B5,     5, 6, 5, 0, 0, 0, 0 },
-      { MESA_A4_R4_G4_B4,  4, 4, 4, 4, 0, 0, 0 },
-      { MESA_A1_R5_G5_B5,  5, 5, 5, 1, 0, 0, 0 },
-      { MESA_A8_R8_G8_B8,  8, 8, 8, 8, 0, 0, 0 },
-      { MESA_FF_R8_G8_B8,  8, 8, 8, 8, 0, 0, 0 },
-      { -1,                0, 0, 0, 0, 0, 0, 0 }
-   };
-   GLint i;
-   for (i = 0; i < bitSizes[i][0] >= 0; i++) {
-      if (bitSizes[i][0] == mesaFormat) {
-         texImage->RedBits       = bitSizes[i][1];
-         texImage->GreenBits     = bitSizes[i][2];
-         texImage->BlueBits      = bitSizes[i][3];
-         texImage->AlphaBits     = bitSizes[i][4];
-         texImage->IntensityBits = bitSizes[i][5];
-         texImage->LuminanceBits = bitSizes[i][6];
-         texImage->IndexBits     = bitSizes[i][7];
-         return;
-      }
+   GLint row, col;
+
+#define INNER_LOOP( HOP, WOP )                                         \
+   for ( row = 0 ; row < dstHeight ; row++ ) {                         \
+      GLint srcRow = row HOP hScale;                                   \
+      for ( col = 0 ; col < dstWidth ; col++ ) {                       \
+        GLint srcCol = col WOP wScale;                                 \
+        *dst++ = src[srcRow * srcWidth + srcCol];                      \
+      }                                                                        \
+   }                                                                   \
+
+#define RESCALE_IMAGE( TYPE )                                          \
+do {                                                                   \
+   const TYPE *src = (const TYPE *)srcImage;                           \
+   TYPE *dst = (TYPE *)dstImage;                                       \
+                                                                       \
+   if ( srcHeight <= dstHeight ) {                                     \
+      const GLint hScale = dstHeight / srcHeight;                      \
+      if ( srcWidth <= dstWidth ) {                                    \
+        const GLint wScale = dstWidth / srcWidth;                      \
+        INNER_LOOP( /, / );                                            \
+      }                                                                        \
+      else {                                                           \
+        const GLint wScale = srcWidth / dstWidth;                      \
+        INNER_LOOP( /, * );                                            \
+      }                                                                        \
+   }                                                                   \
+   else {                                                              \
+      const GLint hScale = srcHeight / dstHeight;                      \
+      if ( srcWidth <= dstWidth ) {                                    \
+        const GLint wScale = dstWidth / srcWidth;                      \
+        INNER_LOOP( *, / );                                            \
+      }                                                                        \
+      else {                                                           \
+        const GLint wScale = srcWidth / dstWidth;                      \
+        INNER_LOOP( *, * );                                            \
+      }                                                                        \
+   }                                                                   \
+} while (0)
+
+   switch ( texFormat->TexelBytes ) {
+   case 4:
+      RESCALE_IMAGE( GLuint );
+      break;
+
+   case 2:
+      RESCALE_IMAGE( GLushort );
+      break;
+
+   case 1:
+      RESCALE_IMAGE( GLubyte );
+      break;
    }
-   _mesa_problem(NULL, "bad format in _mesa_set_teximage_component_sizes");
 }
index 03f7d28bf4d8b130220a6017963b55a9a5ef3fb7..d9293ef8fef1d2dc0458bcad7e6844cc9ffb8869 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: texutil.h,v 1.8 2001/03/12 00:48:39 gareth Exp $ */
+/* $Id: texutil.h,v 1.9 2001/03/18 08:53:50 gareth Exp $ */
 
 /*
  * Mesa 3-D graphics library
  * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ *    Gareth Hughes <gareth@valinux.com>
  */
 
 
 #ifndef TEXUTIL_H
 #define TEXUTIL_H
 
-
 #include "mtypes.h"
-
-
-
-/*
- * NOTE: "FF" means fill with byte value 0xff
- */
-                           /* msb <------ TEXEL BITS -----------> lsb */
-typedef enum {             /* ---- ---- ---- ---- ---- ---- ---- ---- */
-   MESA_I8,                /*                               IIII IIII */
-   MESA_L8,                /*                               LLLL LLLL */
-   MESA_A8,                /*                               AAAA AAAA */
-   MESA_C8,                /*                               CCCC CCCC */
-   MESA_A8_L8,             /*                     AAAA AAAA LLLL LLLL */
-   MESA_R5_G6_B5,          /*                     RRRR RGGG GGGB BBBB */
-   MESA_A4_R4_G4_B4,       /*                     AAAA RRRR GGGG BBBB */
-   MESA_A1_R5_G5_B5,       /*                     ARRR RRGG GGGB BBBB */
-   MESA_A8_R8_G8_B8,       /* AAAA AAAA RRRR RRRR GGGG GGGG BBBB BBBB */
-   MESA_FF_R8_G8_B8        /* FFFF FFFF RRRR RRRR GGGG GGGG BBBB BBBB */
-} MesaIntTexFormat;
-
-
-
+#include "texformat.h"
 
 extern GLboolean
-_mesa_convert_teximage(MesaIntTexFormat dstFormat,
-                       GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
-                       GLint dstRowStride,
-                       GLint srcWidth, GLint srcHeight,
-                       GLenum srcFormat, GLenum srcType,
-                       const GLvoid *srcImage,
-                       const struct gl_pixelstore_attrib *packing);
-
-
+_mesa_convert_texsubimage1d( GLint mesaFormat,
+                            GLint xoffset,
+                            GLint width,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage );
 
 extern GLboolean
-_mesa_convert_texsubimage(MesaIntTexFormat dstFormat,
-                          GLint dstXoffset, GLint dstYoffset,
-                          GLint dstWidth, GLint dstHeight, GLvoid *dstImage,
-                          GLint dstRowStride,
-                          GLint width, GLint height,
-                          GLint srcWidth, GLint srcHeight,
-                          GLenum srcFormat, GLenum srcType,
-                          const GLvoid *srcImage,
-                          const struct gl_pixelstore_attrib *packing);
-
-
-extern void
-_mesa_unconvert_teximage(MesaIntTexFormat srcFormat,
-                         GLint srcWidth, GLint srcHeight,
-                         const GLvoid *srcImage, GLint srcRowStride,
-                         GLint dstWidth, GLint dstHeight,
-                         GLenum dstFormat, GLubyte *dstImage);
-
+_mesa_convert_texsubimage2d( GLint mesaFormat,
+                            GLint xoffset, GLint yoffset,
+                            GLint width, GLint height,
+                            GLint imageWidth,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage );
 
+extern GLboolean
+_mesa_convert_texsubimage3d( GLint mesaFormat,
+                            GLint xoffset, GLint yoffset, GLint zoffset,
+                            GLint width, GLint height, GLint depth,
+                            GLint imageWidth, GLint imageHeight,
+                            GLenum format, GLenum type,
+                            const struct gl_pixelstore_attrib *packing,
+                            const GLvoid *srcImage, GLvoid *dstImage );
+
+/* Nearest filtering only (for broken hardware that can't support
+ * all aspect ratios).  FIXME: Make this a subimage update as well...
+ */
 extern void
-_mesa_set_teximage_component_sizes(MesaIntTexFormat mesaFormat,
-                                   struct gl_texture_image *texImage);
-
+_mesa_rescale_teximage2d( const struct gl_texture_format *texFormat,
+                         GLint srcWidth, GLint srcHeight,
+                         GLint dstWidth, GLint dstHeight,
+                         const GLvoid *srcImage, GLvoid *dstImage );
 
 #endif
diff --git a/src/mesa/main/texutil_tmp.h b/src/mesa/main/texutil_tmp.h
new file mode 100644 (file)
index 0000000..ea6c4ee
--- /dev/null
@@ -0,0 +1,375 @@
+/*
+ * NOTE: All 3D code is untested and most definitely broken...
+ */
+
+#define DST_TEXEL_BYTES                (4 / DST_TEXELS_PER_DWORD)
+#define DST_ROW_WIDTH          (convert->width * DST_TEXEL_BYTES)
+#define DST_ROW_STRIDE         (convert->imageWidth * DST_TEXEL_BYTES)
+#define DST_IMG_STRIDE         (convert->imageWidth *                  \
+                                convert->imageHeight * DST_TEXEL_BYTES)
+
+
+/* ================================================================
+ * PRE: No pixelstore attribs, width == imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)convert->srcImage;
+   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                           (convert->yoffset * convert->imageWidth +
+                            convert->xoffset) * DST_TEXEL_BYTES);
+   GLint dwords, i;
+   (void) dwords; (void) i;
+
+   if ( DBG )
+      fprintf( stderr, __FUNCTION__ "\n" );
+
+#ifdef CONVERT_DIRECT
+   MEMCPY( dst, src, convert->height * DST_ROW_WIDTH );
+#else
+   dwords = (convert->width * convert->height +
+            DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
+
+   for ( i = 0 ; i < dwords ; i++ ) {
+      *dst++ = CONVERT_TEXEL_DWORD( src );
+      src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+   }
+#endif
+
+   return GL_TRUE;
+}
+
+/* PRE: As above, height == imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)convert->srcImage;
+   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                           ((convert->zoffset * convert->height +
+                             convert->yoffset) * convert->width +
+                            convert->xoffset) * DST_TEXEL_BYTES);
+   GLint dwords, i;
+   (void) dwords; (void) i;
+
+   if ( DBG )
+      fprintf( stderr, __FUNCTION__ "\n" );
+
+#ifdef CONVERT_DIRECT
+   MEMCPY( dst, src, convert->depth * convert->height * DST_ROW_WIDTH );
+#else
+   dwords = (convert->width * convert->height * convert->depth +
+            DST_TEXELS_PER_DWORD - 1) / DST_TEXELS_PER_DWORD;
+
+   for ( i = 0 ; i < dwords ; i++ ) {
+      *dst++ = CONVERT_TEXEL_DWORD( src );
+      src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+   }
+#endif
+
+   return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: No pixelstore attribs, width != imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_stride)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)convert->srcImage;
+   DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                               (convert->yoffset * convert->imageWidth +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+   GLint adjust;
+   GLint row, col;
+
+   adjust = convert->imageWidth - convert->width;
+
+   if ( DBG ) {
+      fprintf( stderr, __FUNCTION__ ":\n" );
+      fprintf( stderr, "   x=%d y=%d w=%d h=%d s=%d\n",
+              convert->xoffset, convert->yoffset, convert->width,
+              convert->height, convert->imageWidth );
+      fprintf( stderr, "   adjust=%d\n", adjust );
+   }
+
+   for ( row = 0 ; row < convert->height ; row++ ) {
+      for ( col = 0 ; col < convert->width ; col++ ) {
+        *dst++ = CONVERT_TEXEL( src );
+        src += SRC_TEXEL_BYTES;
+      }
+      dst += adjust;
+   }
+
+   return GL_TRUE;
+}
+
+/* PRE: As above, or height != imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_stride)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)convert->srcImage;
+   DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                               ((convert->zoffset * convert->imageHeight +
+                                 convert->yoffset) * convert->imageWidth +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+   GLint adjust;
+   GLint row, col, img;
+
+   adjust = convert->imageWidth - convert->width;
+
+   if ( DBG ) {
+      fprintf( stderr, __FUNCTION__ ":\n" );
+      fprintf( stderr, "   x=%d y=%d w=%d h=%d s=%d\n",
+              convert->xoffset, convert->yoffset, convert->width,
+              convert->height, convert->imageWidth );
+      fprintf( stderr, "   adjust=%d\n", adjust );
+   }
+
+   for ( img = 0 ; img < convert->depth ; img++ ) {
+      for ( row = 0 ; row < convert->height ; row++ ) {
+        for ( col = 0 ; col < convert->width ; col++ ) {
+           *dst++ = CONVERT_TEXEL( src );
+           src += SRC_TEXEL_BYTES;
+        }
+        dst += adjust;
+      }
+      /* FIXME: ... */
+   }
+
+   return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: Require pixelstore attribs, width == imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_pack)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)
+      _mesa_image_address( convert->packing, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 0, 0, 0 );
+   const GLint srcRowStride =
+      _mesa_image_row_stride( convert->packing, convert->width,
+                             convert->format, convert->type );
+   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                           (convert->yoffset * convert->width +
+                            convert->xoffset) * DST_TEXEL_BYTES);
+   GLint width;
+   GLint row, col;
+   (void) col;
+
+   if ( DBG )
+      fprintf( stderr, __FUNCTION__ "\n" );
+
+   width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
+           & ~(DST_TEXELS_PER_DWORD - 1));
+
+   for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+      MEMCPY( dst, src, DST_ROW_STRIDE );
+      src += srcRowStride;
+      dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+#else
+      const GLubyte *srcRow = src;
+      for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+        *dst++ = CONVERT_TEXEL_DWORD( src );
+        src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+      }
+      src = srcRow + srcRowStride;
+#endif
+   }
+
+   return GL_TRUE;
+}
+
+/* PRE: as above, height == imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_pack)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)
+      _mesa_image_address( convert->packing, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 0, 0, 0 );
+   const GLint srcRowStride =
+      _mesa_image_row_stride( convert->packing, convert->width,
+                             convert->format, convert->type );
+   GLuint *dst = (GLuint *)((GLubyte *)convert->dstImage +
+                           ((convert->zoffset * convert->height +
+                             convert->yoffset) * convert->width +
+                            convert->xoffset) * DST_TEXEL_BYTES);
+   GLint width;
+   GLint row, col, img;
+   (void) col;
+
+   if ( DBG )
+      fprintf( stderr, __FUNCTION__ "\n" );
+
+   width = ((convert->width + DST_TEXELS_PER_DWORD - 1)
+           & ~(DST_TEXELS_PER_DWORD - 1));
+
+   for ( img = 0 ; img < convert->depth ; img++ ) {
+      for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+        MEMCPY( dst, src, DST_ROW_STRIDE );
+        src += srcRowStride;
+        dst = (GLuint *)((GLubyte *)dst + DST_ROW_STRIDE);
+#else
+        const GLubyte *srcRow = src;
+        for ( col = width / DST_TEXELS_PER_DWORD ; col ; col-- ) {
+           *dst++ = CONVERT_TEXEL_DWORD( src );
+           src += SRC_TEXEL_BYTES * DST_TEXELS_PER_DWORD;
+        }
+        src = srcRow + srcRowStride;
+#endif
+      }
+   }
+
+   return GL_TRUE;
+}
+
+
+
+/* ================================================================
+ * PRE: Require pixelstore attribs, width != imageWidth.
+ */
+static GLboolean
+TAG(texsubimage2d_stride_pack)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)
+      _mesa_image_address( convert->packing, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 0, 0, 0 );
+   const GLint srcRowStride =
+      _mesa_image_row_stride( convert->packing, convert->width,
+                             convert->format, convert->type );
+   DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                               (convert->yoffset * convert->imageWidth +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+   GLint adjust;
+   GLint row, col;
+   (void) col;
+
+   adjust = convert->imageWidth - convert->width;
+
+   if ( DBG ) {
+      fprintf( stderr, __FUNCTION__ ":\n" );
+      fprintf( stderr, "   x=%d y=%d w=%d h=%d s=%d\n",
+              convert->xoffset, convert->yoffset, convert->width,
+              convert->height, convert->imageWidth );
+      fprintf( stderr, "   adjust=%d\n", adjust );
+   }
+
+   for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+      MEMCPY( dst, src, DST_ROW_WIDTH );
+      src += srcRowStride;
+      dst += convert->imageWidth;
+#else
+      const GLubyte *srcRow = src;
+      for ( col = 0 ; col < convert->width ; col++ ) {
+        *dst++ = CONVERT_TEXEL( src );
+        src += SRC_TEXEL_BYTES;
+      }
+      src = srcRow + srcRowStride;
+      dst += adjust;
+#endif
+   }
+
+   return GL_TRUE;
+}
+
+/* PRE: As above, or height != imageHeight also.
+ */
+static GLboolean
+TAG(texsubimage3d_stride_pack)( struct gl_texture_convert *convert )
+{
+   const GLubyte *src = (const GLubyte *)
+      _mesa_image_address( convert->packing, convert->srcImage,
+                          convert->width, convert->height,
+                          convert->format, convert->type, 0, 0, 0 );
+   const GLint srcRowStride =
+      _mesa_image_row_stride( convert->packing, convert->width,
+                             convert->format, convert->type );
+   DST_TYPE *dst = (DST_TYPE *)((GLubyte *)convert->dstImage +
+                               ((convert->zoffset * convert->imageHeight +
+                                 convert->yoffset) * convert->imageWidth +
+                                convert->xoffset) * DST_TEXEL_BYTES);
+   GLint adjust;
+   GLint row, col, img;
+   (void) col;
+
+   adjust = convert->imageWidth - convert->width;
+
+   if ( DBG ) {
+      fprintf( stderr, __FUNCTION__ ":\n" );
+      fprintf( stderr, "   x=%d y=%d w=%d h=%d s=%d\n",
+              convert->xoffset, convert->yoffset, convert->width,
+              convert->height, convert->imageWidth );
+      fprintf( stderr, "   adjust=%d\n", adjust );
+   }
+
+   for ( img = 0 ; img < convert->depth ; img++ ) {
+      for ( row = 0 ; row < convert->height ; row++ ) {
+#ifdef CONVERT_DIRECT
+        MEMCPY( dst, src, DST_ROW_WIDTH );
+        src += srcRowStride;
+        dst += convert->imageWidth;
+#else
+        const GLubyte *srcRow = src;
+        for ( col = 0 ; col < convert->width ; col++ ) {
+           *dst++ = CONVERT_TEXEL( src );
+           src += SRC_TEXEL_BYTES;
+        }
+        src = srcRow + srcRowStride;
+        dst += adjust;
+#endif
+      }
+      /* FIXME: ... */
+   }
+
+   return GL_TRUE;
+}
+
+
+
+static convert_func TAG(texsubimage2d_tab)[] = {
+   TAG(texsubimage2d),
+   TAG(texsubimage2d_stride),
+   TAG(texsubimage2d_pack),
+   TAG(texsubimage2d_stride_pack),
+};
+
+static convert_func TAG(texsubimage3d_tab)[] = {
+   TAG(texsubimage3d),
+   TAG(texsubimage3d_stride),
+   TAG(texsubimage3d_pack),
+   TAG(texsubimage3d_stride_pack),
+};
+
+
+#ifndef PRESERVE_DST_TYPE
+#undef DST_TYPE
+#undef DST_TEXELS_PER_DWORD
+#endif
+
+#undef SRC_TEXEL_BYTES
+#undef DST_TEXEL_BYTES
+#undef DST_ROW_WIDTH
+#undef DST_ROW_STRIDE
+
+#undef CONVERT_TEXEL
+#undef CONVERT_TEXEL_DWORD
+#undef CONVERT_DIRECT
+
+#undef TAG
+
+#undef PRESERVE_DST_TYPE