From 2c3d34c905fa6b831a066afae83b938de05eb241 Mon Sep 17 00:00:00 2001 From: Gareth Hughes Date: Sun, 18 Mar 2001 08:53:49 +0000 Subject: [PATCH] - Port 3.4 texture utils, texture format work to 3.5 (including new FetchTexel routines). - Initial hooks for GL_EXT_texture_filter_anisotropic. --- src/mesa/Makefile.X11 | 3 +- src/mesa/main/Makefile.X11 | 3 +- src/mesa/main/attrib.c | 3 +- src/mesa/main/config.h | 5 +- src/mesa/main/context.c | 3 +- src/mesa/main/extensions.c | 109 +- src/mesa/main/get.c | 46 +- src/mesa/main/macros.h | 29 +- src/mesa/main/mtypes.h | 36 +- src/mesa/main/texformat.c | 566 ++++++++ src/mesa/main/texformat.h | 123 ++ src/mesa/main/texformat_tmp.h | 264 ++++ src/mesa/main/teximage.c | 29 +- src/mesa/main/texobj.c | 3 +- src/mesa/main/texstate.c | 31 +- src/mesa/main/texstore.c | 84 +- src/mesa/main/texutil.c | 2388 +++++++++++---------------------- src/mesa/main/texutil.h | 88 +- src/mesa/main/texutil_tmp.h | 375 ++++++ 19 files changed, 2364 insertions(+), 1824 deletions(-) create mode 100644 src/mesa/main/texformat.c create mode 100644 src/mesa/main/texformat.h create mode 100644 src/mesa/main/texformat_tmp.h create mode 100644 src/mesa/main/texutil_tmp.h diff --git a/src/mesa/Makefile.X11 b/src/mesa/Makefile.X11 index fdab3399ce3..24109a739ce 100644 --- a/src/mesa/Makefile.X11 +++ b/src/mesa/Makefile.X11 @@ -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 \ diff --git a/src/mesa/main/Makefile.X11 b/src/mesa/main/Makefile.X11 index fdab3399ce3..24109a739ce 100644 --- a/src/mesa/main/Makefile.X11 +++ b/src/mesa/main/Makefile.X11 @@ -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 \ diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 700106ea8f1..a26dcd2e3e9 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -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; diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index dff7c401380..c5392d724b3 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -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 @@ -125,6 +125,9 @@ /* GL_ARB_texture_compression */ #define MAX_COMPRESSED_TEXTURE_FORMATS 25 +/* GL_EXT_texture_filter_anisotropic */ +#define MAX_TEXTURE_MAX_ANISOTROPY 16.0 + /* diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index b732889cdf4..013a16b95be 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -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; diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 1b5c9cd448e..6a7d25fe201 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -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) } }; diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 83c4d16f3af..c721bd4bfd9 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -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) { diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index 1cfb55552d3..b9ccd906d4c 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -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 diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index f54b8d5fa9d..1ed5bad4c24 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -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 index 00000000000..d7b8024161f --- /dev/null +++ b/src/mesa/main/texformat.c @@ -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 + */ + +#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 index 00000000000..c6b897f5445 --- /dev/null +++ b/src/mesa/main/texformat.h @@ -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 + */ + +#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 index 00000000000..77084ebebac --- /dev/null +++ b/src/mesa/main/texformat_tmp.h @@ -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 diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index 5a231d182dc..d44b5d6ee67 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -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) { diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 0bcc0deae8b..da4c6360563 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -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; diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index d21503ac03e..1a6a42a85c9 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -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; diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 3354f864070..8fa9deb2218 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -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; } diff --git a/src/mesa/main/texutil.c b/src/mesa/main/texutil.c index 345d431d6ec..dc963551ac1 100644 --- a/src/mesa/main/texutil.c +++ b/src/mesa/main/texutil.c @@ -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 @@ -22,1662 +22,834 @@ * 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 */ - #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"); } diff --git a/src/mesa/main/texutil.h b/src/mesa/main/texutil.h index 03f7d28bf4d..d9293ef8fef 100644 --- a/src/mesa/main/texutil.h +++ b/src/mesa/main/texutil.h @@ -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 @@ -22,71 +22,51 @@ * 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 */ #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 index 00000000000..ea6c4ee52c7 --- /dev/null +++ b/src/mesa/main/texutil_tmp.h @@ -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 -- 2.30.2