From 1c2a498119d3b6a194033bca6bfe5d3fb4665371 Mon Sep 17 00:00:00 2001 From: Daniel Borca Date: Mon, 19 Jul 2004 08:06:00 +0000 Subject: [PATCH] several new bugs --- src/mesa/drivers/dri/tdfx/tdfx_context.c | 120 ++- src/mesa/drivers/dri/tdfx/tdfx_context.h | 78 +- src/mesa/drivers/dri/tdfx/tdfx_dd.c | 2 +- src/mesa/drivers/dri/tdfx/tdfx_render.c | 24 +- src/mesa/drivers/dri/tdfx/tdfx_state.c | 207 ++-- src/mesa/drivers/dri/tdfx/tdfx_tex.c | 1070 ++++++++++++++------- src/mesa/drivers/dri/tdfx/tdfx_texman.c | 4 +- src/mesa/drivers/dri/tdfx/tdfx_texstate.c | 217 +++-- src/mesa/drivers/dri/tdfx/tdfx_tris.c | 380 ++++---- src/mesa/drivers/dri/tdfx/tdfx_vb.c | 107 ++- src/mesa/drivers/dri/tdfx/tdfx_vb.h | 3 +- src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h | 325 +++---- 12 files changed, 1521 insertions(+), 1016 deletions(-) diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.c b/src/mesa/drivers/dri/tdfx/tdfx_context.c index fe23a15925d..ea9ec077cd7 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.c @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.c,v 1.12 2003/05/08 09:25:35 herrb Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -68,7 +71,16 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) _mesa_enable_extension( ctx, "GL_HP_occlusion_test" ); _mesa_enable_extension( ctx, "GL_EXT_paletted_texture" ); + _mesa_enable_extension( ctx, "GL_EXT_shared_texture_palette" ); _mesa_enable_extension( ctx, "GL_EXT_texture_lod_bias" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_func_separate" ); + _mesa_enable_extension( ctx, "GL_EXT_fog_coord" ); + +#if 0 + _mesa_enable_extension(ctx, "GL_EXT_secondary_color"); + _mesa_enable_extension(ctx, "GL_ARB_point_sprite"); + _mesa_enable_extension(ctx, "GL_EXT_point_parameters"); +#endif if ( fxMesa->haveTwoTMUs ) { _mesa_enable_extension( ctx, "GL_EXT_texture_env_add" ); @@ -76,21 +88,41 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) } if ( TDFX_IS_NAPALM( fxMesa ) ) { -#if 0 _mesa_enable_extension( ctx, "GL_ARB_texture_compression" ); _mesa_enable_extension( ctx, "GL_3DFX_texture_compression_FXT1" ); -#endif - _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); - } + _mesa_enable_extension( ctx, "GL_EXT_texture_compression_s3tc" ); + _mesa_enable_extension( ctx, "GL_S3_s3tc" ); -#if 0 - _mesa_enable_extension( ctx, "GL_ARB_texture_cube_map"); - _mesa_enable_extension( ctx, "GL_NV_texture_rectangle"); -#endif + _mesa_enable_extension( ctx, "GL_NV_blend_square" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_subtract" ); + _mesa_enable_extension( ctx, "GL_EXT_blend_equation_separate" ); + } else { + _mesa_enable_extension( ctx, "GL_SGIS_generate_mipmap" ); + } if (fxMesa->haveHwStencil) { _mesa_enable_extension( ctx, "GL_EXT_stencil_wrap" ); } + + if (1/*fxMesa->Glide.HaveMirrorExt - JJJ*/) { + _mesa_enable_extension(ctx, "GL_ARB_texture_mirrored_repeat"); + } + + if (TDFX_IS_NAPALM(fxMesa)/*fxMesa->Glide.HaveCombineExt - JJJ*/) { + _mesa_enable_extension( ctx, "GL_EXT_texture_env_combine" ); + } + + /* core-level extensions */ + _mesa_enable_extension(ctx, "GL_EXT_multi_draw_arrays"); + _mesa_enable_extension(ctx, "GL_IBM_multimode_draw_arrays"); + _mesa_enable_extension(ctx, "GL_ARB_vertex_buffer_object"); +#if 0 + /* not just yet */ + _mesa_enable_extension(ctx, "GL_ARB_vertex_program"); + _mesa_enable_extension(ctx, "GL_NV_vertex_program"); + _mesa_enable_extension(ctx, "GL_NV_vertex_program1_1"); + _mesa_enable_extension(ctx, "GL_MESA_program_debug"); +#endif } @@ -98,10 +130,16 @@ static void tdfxDDInitExtensions( GLcontext *ctx ) static const struct tnl_pipeline_stage *tdfx_pipeline[] = { &_tnl_vertex_transform_stage, &_tnl_normal_transform_stage, - &_tnl_lighting_stage, /* REMOVE: fog coord stage */ + &_tnl_lighting_stage, + &_tnl_fog_coordinate_stage, &_tnl_texgen_stage, &_tnl_texture_transform_stage, - /* REMOVE: point attenuation stage */ + &_tnl_point_attenuation_stage, +#if 0 +#if defined(FEATURE_NV_vertex_program) || defined(FEATURE_ARB_vertex_program) + &_tnl_vertex_program_stage, +#endif +#endif &_tnl_render_stage, 0, }; @@ -157,6 +195,10 @@ GLboolean tdfxCreateContext( const __GLcontextModes *mesaVis, fxMesa->fxScreen = fxScreen; fxMesa->sarea = saPriv; + /*JJJ - really?*/ + fxMesa->haveHwAlpha = ( mesaVis->alphaBits && + ((mesaVis->greenBits == 8) || + (mesaVis->depthBits == 0)) ); fxMesa->haveHwStencil = ( TDFX_IS_NAPALM( fxMesa ) && mesaVis->stencilBits && mesaVis->depthBits == 24 ); @@ -293,7 +335,7 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); - fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_TINY] ); /* Non textured vertex format - 24 bytes (Need w for table fog) @@ -315,7 +357,6 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); - /*grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_SINGLE] ); /* Multitextured vertex format - 40 bytes. @@ -328,10 +369,21 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); - /*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_MULTI] ); - /* Projected texture vertex format - 48 bytes. + /* Projected texture vertex format - 36 bytes. + */ + fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); + fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); + fxMesa->Glide.grVertexLayout( GR_PARAM_XY, TDFX_XY_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Z, TDFX_Z_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Q, TDFX_Q_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_PARGB, TDFX_ARGB_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_ST0, TDFX_ST0_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE ); + fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJ1] ); + + /* Projected multitexture vertex format - 48 bytes. */ fxMesa->Glide.grReset( GR_VERTEX_PARAMETER ); fxMesa->Glide.grCoordinateSpace( GR_WINDOW_COORDS ); @@ -343,8 +395,7 @@ static GLboolean tdfxInitVertexFormats( tdfxContextPtr fxMesa ) fxMesa->Glide.grVertexLayout( GR_PARAM_Q0, TDFX_Q0_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_ST1, TDFX_ST1_OFFSET, GR_PARAM_ENABLE ); fxMesa->Glide.grVertexLayout( GR_PARAM_Q1, TDFX_Q1_OFFSET, GR_PARAM_ENABLE ); - /*fxMesa->Glide.grVertexLayout( GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, GR_PARAM_ENABLE );*/ - fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJECT] ); + fxMesa->Glide.grGlideGetVertexLayout( fxMesa->layout[TDFX_LAYOUT_PROJ2] ); UNLOCK_HARDWARE( fxMesa ); @@ -361,6 +412,7 @@ tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa ) /* KW: Would be nice to make one of these a member of the other. */ FxI32 result[2]; + const char *gext; if ( TDFX_DEBUG & DEBUG_VERBOSE_DRI ) { fprintf( stderr, "%s( %p )\n", __FUNCTION__, (void *)fxMesa ); @@ -407,6 +459,18 @@ tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa ) LOCK_HARDWARE( fxMesa ); + /* JJJ - COMMAND_TRANSPORT, PALETTE6666 */ + gext = fxMesa->Glide.grGetString( GR_EXTENSION ); + fxMesa->Glide.HaveCombineExt = strstr(gext, "COMBINE") && !getenv("MESA_FX_IGNORE_CMBEXT"); + fxMesa->Glide.HaveCommandTransportExt = GL_FALSE; + fxMesa->Glide.HaveFogCoordExt = GL_TRUE; + fxMesa->Glide.HavePixelExt = strstr(gext, "PIXEXT") && !getenv("MESA_FX_IGNORE_PIXEXT"); + fxMesa->Glide.HaveTextureBufferExt = GL_TRUE; + fxMesa->Glide.HaveTexFmtExt = strstr(gext, "TEXFMT") && !getenv("MESA_FX_IGNORE_TEXFMT"); + fxMesa->Glide.HaveTexUMAExt = strstr(gext, "TEXUMA") && !getenv("MESA_FX_IGNORE_TEXUMA"); + fxMesa->Glide.HaveMirrorExt = strstr(gext, "TEXMIRROR") && !getenv("MESA_FX_IGNORE_MIREXT"); + fxMesa->Glide.HaveTexus2 = GL_FALSE; + if ( fxMesa->glCtx->Visual.depthBits > 0 ) { fxMesa->Glide.grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER); } else { @@ -449,7 +513,7 @@ tdfxInitContext( __DRIdrawablePrivate *driDrawPriv, tdfxContextPtr fxMesa ) printf( "GR_VERSION = %s\n", (char *) fxMesa->Glide.grGetString( GR_VERSION ) ); printf( "GR_VENDOR = %s\n", (char *) fxMesa->Glide.grGetString( GR_VENDOR ) ); printf( "GR_HARDWARE = %s\n", (char *) fxMesa->Glide.grGetString( GR_HARDWARE ) ); - printf( "GR_EXTENSION = %s\n", (char *) fxMesa->Glide.grGetString( GR_EXTENSION ) ); + printf( "GR_EXTENSION = %s\n", (char *) gext ); } UNLOCK_HARDWARE( fxMesa ); @@ -550,15 +614,19 @@ tdfxMakeCurrent( __DRIcontextPrivate *driContextPriv, newFx->driDrawable = driDrawPriv; newFx->dirty = ~0; } - else if (curCtx == newCtx) { - /* same drawable, same context -> no-op */ - /* Need to call _mesa_make_current2() in order to make sure API - * dispatch is set correctly. - */ - _mesa_make_current2( newCtx, - (GLframebuffer *) driDrawPriv->driverPrivate, - (GLframebuffer *) driReadPriv->driverPrivate ); - return GL_TRUE; + else { + if (curCtx == newCtx) { + /* same drawable, same context -> no-op */ + /* Need to call _mesa_make_current2() in order to make sure API + * dispatch is set correctly. + */ + _mesa_make_current2( newCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + return GL_TRUE; + } + /* [dBorca] tunnel2 requires this */ + newFx->dirty = ~0; } if ( !newFx->Glide.Initialized ) { diff --git a/src/mesa/drivers/dri/tdfx/tdfx_context.h b/src/mesa/drivers/dri/tdfx/tdfx_context.h index 201fce1a012..5af5a3d16ac 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_context.h +++ b/src/mesa/drivers/dri/tdfx/tdfx_context.h @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_context.h,v 1.5 2002/02/24 21:51:10 dawes Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -108,6 +111,7 @@ #define TDFX_UPLOAD_FOG_MODE 0x00000400 #define TDFX_UPLOAD_FOG_COLOR 0x00000800 #define TDFX_UPLOAD_FOG_TABLE 0x00001000 +#define TDFX_UPLOAD_CONSTANT_COLOR 0x00002000 #define TDFX_UPLOAD_CLIP 0x00002000 #define TDFX_UPLOAD_CULL 0x00004000 @@ -128,7 +132,7 @@ /* Flags for software fallback cases */ /* See correponding strings in tdfx_tris.c */ -#define TDFX_FALLBACK_TEXTURE_1D_3D 0x0001 +#define TDFX_FALLBACK_TEXTURE_MAP 0x0001 #define TDFX_FALLBACK_DRAW_BUFFER 0x0002 #define TDFX_FALLBACK_SPECULAR 0x0004 #define TDFX_FALLBACK_STENCIL 0x0008 @@ -146,15 +150,15 @@ #define TDFX_LAYOUT_NOTEX 1 #define TDFX_LAYOUT_SINGLE 2 #define TDFX_LAYOUT_MULTI 3 -#define TDFX_LAYOUT_PROJECT 4 -#define TDFX_NUM_LAYOUTS 5 +#define TDFX_LAYOUT_PROJ1 4 +#define TDFX_LAYOUT_PROJ2 5 +#define TDFX_NUM_LAYOUTS 6 #define TDFX_XY_OFFSET 0 #define TDFX_Z_OFFSET 8 #define TDFX_Q_OFFSET 12 #define TDFX_ARGB_OFFSET 16 -#define TDFX_PAD_OFFSET 20 -#define TDFX_FOG_OFFSET 20 /* experimental */ +#define TDFX_FOG_OFFSET 20 #define TDFX_ST0_OFFSET 24 #define TDFX_ST1_OFFSET 32 #define TDFX_Q0_OFFSET 40 @@ -316,7 +320,10 @@ typedef struct tdfxTexInfo_t GLfloat sScale, tScale; /* texcoord scale factor */ + GrTexTable_t paltype; GuTexPalette palette; + + GLboolean padded; } tdfxTexInfo; @@ -344,49 +351,20 @@ struct tdfxSharedState { /* ================================================================ * The vertex structures. */ -typedef struct { - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; -} tdfx_color_t; - -typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - tdfx_color_t color; /* Diffuse color */ - GLuint pad; - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ -} tdfx_vertex; - -typedef struct { +/* The size of this union is not of relevence: + */ +typedef struct tdfx_vertex_t { GLfloat x, y, z; /* Coordinates in screen space */ GLfloat rhw; /* Reciprocal homogeneous w */ - tdfx_color_t color; /* Diffuse color */ - GLuint pad; + GLubyte color[4]; /* Diffuse color */ + GLfloat fog; GLfloat tu0, tv0; /* Texture 0 coordinates */ GLfloat tu1, tv1; /* Texture 1 coordinates */ GLfloat tq0, tq1; /* Texture 0/1 q coords */ -} tdfx_ptex_vertex; - -typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - tdfx_color_t color; /* Diffuse color */ -} tdfx_tiny_vertex; - -/* The size of this union is not of relevence: - */ -union tdfx_vertex_t { - tdfx_vertex v; - tdfx_tiny_vertex tv; - tdfx_ptex_vertex pv; - GLfloat f[16]; - GLuint ui[16]; - GLubyte ub4[16][4]; -}; - -typedef union tdfx_vertex_t tdfxVertex, *tdfxVertexPtr; + unsigned char pspec[4]; /* B, G, R, A [0..255] */ + float psize; /* point size */ + long pad[16 - 14]; /* ensure 64b structure */ +} tdfxVertex, *tdfxVertexPtr; /* ================================================================ @@ -528,8 +506,10 @@ struct tdfx_color { /* Blending */ GrAlphaBlendFnc_t BlendSrcRGB; /* Blend source RGB factor */ GrAlphaBlendFnc_t BlendDstRGB; /* Blend destination RGB factor */ + GrAlphaBlendOp_t BlendEqRGB; /* Blend source RGB op */ GrAlphaBlendFnc_t BlendSrcA; /* Blend source alpha factor */ GrAlphaBlendFnc_t BlendDstA; /* Blend destination alpha factor */ + GrAlphaBlendOp_t BlendEqA; /* Blend source alpha op */ GrDitherMode_t Dither; /* Dither enable */ }; @@ -601,6 +581,7 @@ struct tdfx_glide { FxBool HaveTextureBufferExt; /* TEXTUREBUFFER */ FxBool HaveTexFmtExt; /* TEXFMT */ FxBool HaveTexUMAExt; /* TEXUMA */ + FxBool HaveMirrorExt; /* MIRROR */ FxBool HaveTexus2; /* Texus 2 - FXT1 */ /* Glide library function pointers */ @@ -838,6 +819,7 @@ struct tdfx_context { /* Mirror of hardware state, Glide parameters */ + GLuint tmu_source[TDFX_NUM_TMU]; struct tdfx_texsource TexSource[TDFX_NUM_TMU]; struct tdfx_texparams TexParams[TDFX_NUM_TMU]; struct tdfx_texpalette TexPalette; @@ -879,10 +861,9 @@ struct tdfx_context { /* Variable-size Glide vertex formats */ - GLuint vertexFormat; /* the current format */ - GLuint vertex_stride_shift; + GLuint vertexFormat; /* the current format */ void *layout[TDFX_NUM_LAYOUTS]; - GLubyte *verts; /* tdfxVertices, arbitarily packed */ + tdfxVertex *verts; GLfloat hw_viewport[16]; @@ -903,6 +884,7 @@ struct tdfx_context { int screen_height; GLboolean haveTwoTMUs; /* True if we have 2 tmu's */ + GLboolean haveHwAlpha; GLboolean haveHwStencil; GLboolean haveHwStipple; @@ -1019,6 +1001,10 @@ extern int TDFX_DEBUG; #define DEBUG_VERBOSE_IOCTL 0x20 #define DEBUG_VERBOSE_2D 0x40 +/* conf */ +#define FX_COMPRESS_S3TC_AS_FXT1_HACK 1 +#define FX_TC_NAPALM 0 + #endif /* GLX_DIRECT_RENDERING */ #endif /* __TDFX_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/tdfx/tdfx_dd.c b/src/mesa/drivers/dri/tdfx/tdfx_dd.c index 367b0d241ef..34e4babcf5e 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_dd.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_dd.c @@ -49,7 +49,7 @@ #endif -#define TDFX_DATE "20021125" +#define TDFX_DATE "20040719" /* These are used in calls to FX_grColorMaskv() */ diff --git a/src/mesa/drivers/dri/tdfx/tdfx_render.c b/src/mesa/drivers/dri/tdfx/tdfx_render.c index e15b38034e9..1ab38a56625 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_render.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_render.c @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_render.c,v 1.4 2002/02/22 21:45:03 dawes Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -95,7 +98,7 @@ static void tdfxClear( GLcontext *ctx, fxMesa->Glide.grStencilMask(/*ctx->Stencil.WriteMask*/ 0xff); /* set stencil ref value = desired clear value */ fxMesa->Glide.grStencilFunc(GR_CMP_ALWAYS, - ctx->Stencil.Clear, 0xff); + fxMesa->Stencil.Clear, 0xff); fxMesa->Glide.grStencilOp(GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE, GR_STENCILOP_REPLACE); fxMesa->Glide.grEnable(GR_STENCIL_MODE_EXT); @@ -532,8 +535,8 @@ static void uploadTextureImages( tdfxContextPtr fxMesa ) GLcontext *ctx = fxMesa->glCtx; int unit; for (unit = 0; unit < TDFX_NUM_TMU; unit++) { - if (ctx->Texture.Unit[unit]._ReallyEnabled == TEXTURE_2D_BIT) { - struct gl_texture_object *tObj = ctx->Texture.Unit[unit].Current2D; + if (ctx->Texture.Unit[unit]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { + struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; tdfxTexInfo *ti = TDFX_TEXTURE_DATA(tObj); if (ti && ti->reloadImages && ti->whichTMU != TDFX_TMU_NONE) { /* @@ -653,10 +656,10 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) if (fxMesa->Glide.grAlphaBlendFunctionExt) { fxMesa->Glide.grAlphaBlendFunctionExt( fxMesa->Color.BlendSrcRGB, fxMesa->Color.BlendDstRGB, - GR_BLEND_OP_ADD, + fxMesa->Color.BlendEqRGB, fxMesa->Color.BlendSrcA, fxMesa->Color.BlendDstA, - GR_BLEND_OP_ADD ); + fxMesa->Color.BlendEqA ); } else { fxMesa->Glide.grAlphaBlendFunction( fxMesa->Color.BlendSrcRGB, @@ -727,10 +730,10 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) fxMesa->dirty &= ~TDFX_UPLOAD_COLOR_MASK; } -/* if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { */ -/* grConstantColorValue( fxMesa->Color.MonoColor ); */ -/* fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; */ -/* } */ + if ( fxMesa->dirty & TDFX_UPLOAD_CONSTANT_COLOR ) { + fxMesa->Glide.grConstantColorValue( fxMesa->Color.MonoColor ); + fxMesa->dirty &= ~TDFX_UPLOAD_CONSTANT_COLOR; + } if ( fxMesa->dirty & TDFX_UPLOAD_LINE ) { if (fxMesa->glCtx->Line.SmoothFlag && fxMesa->glCtx->Line.Width == 1.0) @@ -759,6 +762,9 @@ void tdfxEmitHwStateLocked( tdfxContextPtr fxMesa ) if ( fxMesa->dirty & TDFX_UPLOAD_VERTEX_LAYOUT ) { fxMesa->Glide.grGlideSetVertexLayout( fxMesa->layout[fxMesa->vertexFormat] ); + /* [dborca] enable fogcoord */ + fxMesa->Glide.grVertexLayout(GR_PARAM_FOG_EXT, TDFX_FOG_OFFSET, + fxMesa->Fog.Mode == GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT); fxMesa->dirty &= ~TDFX_UPLOAD_VERTEX_LAYOUT; } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_state.c b/src/mesa/drivers/dri/tdfx/tdfx_state.c index dffcccd9a21..7f1ce3c004d 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_state.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_state.c @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_state.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -68,40 +71,19 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); GrCmpFnc_t func; GrAlphaBlendFnc_t srcRGB, dstRGB, srcA, dstA; + GrAlphaBlendOp_t eqRGB, eqA; GrAlpha_t ref = (GLint) (ctx->Color.AlphaRef * 255.0); + + GLboolean isNapalm = TDFX_IS_NAPALM(fxMesa); + GLboolean have32bpp = (ctx->Visual.greenBits == 8); + GLboolean haveAlpha = fxMesa->haveHwAlpha; if ( TDFX_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s()\n", __FUNCTION__ ); } if ( ctx->Color.AlphaEnabled ) { - switch ( ctx->Color.AlphaFunc ) { - case GL_NEVER: - func = GR_CMP_NEVER; - break; - case GL_LESS: - func = GR_CMP_LESS; - break; - case GL_LEQUAL: - func = GR_CMP_LEQUAL; - break; - case GL_EQUAL: - func = GR_CMP_EQUAL; - break; - case GL_GEQUAL: - func = GR_CMP_GEQUAL; - break; - case GL_GREATER: - func = GR_CMP_GREATER; - break; - case GL_NOTEQUAL: - func = GR_CMP_NOTEQUAL; - break; - case GL_ALWAYS: - default: - func = GR_CMP_ALWAYS; - break; - } + func = ctx->Color.AlphaFunc - GL_NEVER + GR_CMP_NEVER; } else { func = GR_CMP_ALWAYS; } @@ -128,14 +110,24 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) srcRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: - srcRGB = GR_BLEND_DST_ALPHA; + srcRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_ALPHA: - srcRGB = GR_BLEND_ONE_MINUS_DST_ALPHA; + srcRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_SRC_ALPHA_SATURATE: srcRGB = GR_BLEND_ALPHA_SATURATE; break; + case GL_SRC_COLOR: + if (isNapalm) { + srcRGB = GR_BLEND_SAME_COLOR_EXT; + break; + } + case GL_ONE_MINUS_SRC_COLOR: + if (isNapalm) { + srcRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; + break; + } default: srcRGB = GR_BLEND_ONE; } @@ -147,23 +139,21 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) case GL_ONE: srcA = GR_BLEND_ONE; break; - case GL_DST_COLOR: - srcA = GR_BLEND_DST_ALPHA; /* Napalm only */ - break; - case GL_ONE_MINUS_DST_COLOR: - srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ - break; + case GL_SRC_COLOR: case GL_SRC_ALPHA: - srcA = GR_BLEND_SRC_ALPHA; /* Napalm only */ + srcA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/; break; + case GL_ONE_MINUS_SRC_COLOR: case GL_ONE_MINUS_SRC_ALPHA: - srcA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ + srcA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ONE/*JJJ*/; break; + case GL_DST_COLOR: case GL_DST_ALPHA: - srcA = GR_BLEND_DST_ALPHA; /* Napalm only */ + srcA = (have32bpp && haveAlpha) ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; + case GL_ONE_MINUS_DST_COLOR: case GL_ONE_MINUS_DST_ALPHA: - srcA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ + srcA = (have32bpp && haveAlpha) ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; case GL_SRC_ALPHA_SATURATE: srcA = GR_BLEND_ONE; @@ -192,11 +182,21 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) dstRGB = GR_BLEND_ONE_MINUS_SRC_ALPHA; break; case GL_DST_ALPHA: - dstRGB = GR_BLEND_DST_ALPHA; + dstRGB = haveAlpha ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; case GL_ONE_MINUS_DST_ALPHA: - dstRGB = GR_BLEND_ONE_MINUS_DST_ALPHA; + dstRGB = haveAlpha ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; + case GL_DST_COLOR: + if (isNapalm) { + srcRGB = GR_BLEND_SAME_COLOR_EXT; + break; + } + case GL_ONE_MINUS_DST_COLOR: + if (isNapalm) { + srcRGB = GR_BLEND_ONE_MINUS_SAME_COLOR_EXT; + break; + } default: dstRGB = GR_BLEND_ZERO; } @@ -209,32 +209,58 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) dstA = GR_BLEND_ONE; break; case GL_SRC_COLOR: - dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */ - break; - case GL_ONE_MINUS_SRC_COLOR: - dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ - break; case GL_SRC_ALPHA: - dstA = GR_BLEND_SRC_ALPHA; /* Napalm only */ + dstA = have32bpp ? GR_BLEND_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; + case GL_ONE_MINUS_SRC_COLOR: case GL_ONE_MINUS_SRC_ALPHA: - dstA = GR_BLEND_ONE_MINUS_SRC_ALPHA; /* Napalm only */ + dstA = have32bpp ? GR_BLEND_ONE_MINUS_SRC_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; + case GL_DST_COLOR: case GL_DST_ALPHA: - dstA = GR_BLEND_DST_ALPHA; /* Napalm only */ + dstA = have32bpp ? GR_BLEND_DST_ALPHA : GR_BLEND_ONE/*JJJ*/; break; + case GL_ONE_MINUS_DST_COLOR: case GL_ONE_MINUS_DST_ALPHA: - dstA = GR_BLEND_ONE_MINUS_DST_ALPHA; /* Napalm only */ + dstA = have32bpp ? GR_BLEND_ONE_MINUS_DST_ALPHA : GR_BLEND_ZERO/*JJJ*/; break; default: dstA = GR_BLEND_ZERO; } + + switch ( ctx->Color.BlendEquationRGB ) { + case GL_FUNC_SUBTRACT: + eqRGB = GR_BLEND_OP_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqRGB = GR_BLEND_OP_REVSUB; + break; + case GL_FUNC_ADD: + default: + eqRGB = GR_BLEND_OP_ADD; + break; + } + + switch ( ctx->Color.BlendEquationA ) { + case GL_FUNC_SUBTRACT: + eqA = GR_BLEND_OP_SUB; + break; + case GL_FUNC_REVERSE_SUBTRACT: + eqA = GR_BLEND_OP_REVSUB; + break; + case GL_FUNC_ADD: + default: + eqA = GR_BLEND_OP_ADD; + break; + } } else { /* blend disabled */ srcRGB = GR_BLEND_ONE; dstRGB = GR_BLEND_ZERO; + eqRGB = GR_BLEND_OP_ADD; srcA = GR_BLEND_ONE; dstA = GR_BLEND_ZERO; + eqA = GR_BLEND_OP_ADD; } if ( fxMesa->Color.AlphaFunc != func ) { @@ -248,13 +274,17 @@ static void tdfxUpdateAlphaMode( GLcontext *ctx ) if ( fxMesa->Color.BlendSrcRGB != srcRGB || fxMesa->Color.BlendDstRGB != dstRGB || + fxMesa->Color.BlendEqRGB != eqRGB || fxMesa->Color.BlendSrcA != srcA || - fxMesa->Color.BlendDstA != dstA ) + fxMesa->Color.BlendDstA != dstA || + fxMesa->Color.BlendEqA != eqA ) { fxMesa->Color.BlendSrcRGB = srcRGB; fxMesa->Color.BlendDstRGB = dstRGB; + fxMesa->Color.BlendEqRGB = eqRGB; fxMesa->Color.BlendSrcA = srcA; fxMesa->Color.BlendDstA = dstA; + fxMesa->Color.BlendEqA = eqA; fxMesa->dirty |= TDFX_UPLOAD_BLEND_FUNC; } } @@ -337,40 +367,8 @@ static void tdfxUpdateZMode( GLcontext *ctx ) bias = (FxI32) (ctx->Polygon.OffsetUnits * TDFX_DEPTH_BIAS_SCALE); if ( ctx->Depth.Test ) { - switch ( ctx->Depth.Func ) { - case GL_NEVER: - func = GR_CMP_NEVER; - break; - case GL_LESS: - func = GR_CMP_LESS; - break; - case GL_LEQUAL: - func = GR_CMP_LEQUAL; - break; - case GL_EQUAL: - func = GR_CMP_EQUAL; - break; - case GL_GEQUAL: - func = GR_CMP_GEQUAL; - break; - case GL_GREATER: - func = GR_CMP_GREATER; - break; - case GL_NOTEQUAL: - func = GR_CMP_NOTEQUAL; - break; - case GL_ALWAYS: - default: - func = GR_CMP_ALWAYS; - break; - } - - if ( ctx->Depth.Mask ) { - mask = FXTRUE; - } - else { - mask = FXFALSE; - } + func = ctx->Depth.Func - GL_NEVER + GR_CMP_NEVER; + mask = ctx->Depth.Mask; } else { /* depth testing disabled */ @@ -378,8 +376,7 @@ static void tdfxUpdateZMode( GLcontext *ctx ) mask = FXFALSE; /* zbuffer is not touched */ } - fxMesa->Depth.Clear = (FxU32) (((1 << fxMesa->glCtx->Visual.depthBits) - 1) - * ctx->Depth.Clear); + fxMesa->Depth.Clear = (FxU32) (ctx->DepthMaxF * ctx->Depth.Clear); if ( fxMesa->Depth.Bias != bias ) { fxMesa->Depth.Bias = bias; @@ -464,7 +461,7 @@ static void tdfxUpdateStencil( GLcontext *ctx ) if (fxMesa->haveHwStencil) { if (ctx->Stencil.Enabled) { - fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER; + fxMesa->Stencil.Function = ctx->Stencil.Function[0] - GL_NEVER + GR_CMP_NEVER; fxMesa->Stencil.RefValue = ctx->Stencil.Ref[0]; fxMesa->Stencil.ValueMask = ctx->Stencil.ValueMask[0]; fxMesa->Stencil.WriteMask = ctx->Stencil.WriteMask[0]; @@ -520,7 +517,11 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx ) } if ( ctx->Fog.Enabled ) { - mode = GR_FOG_WITH_TABLE_ON_Q; + if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT) { + mode = GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT; + } else { + mode = GR_FOG_WITH_TABLE_ON_Q; + } } else { mode = GR_FOG_DISABLE; } @@ -532,6 +533,7 @@ static void tdfxUpdateFogAttrib( GLcontext *ctx ) if ( fxMesa->Fog.Mode != mode ) { fxMesa->Fog.Mode = mode; fxMesa->dirty |= TDFX_UPLOAD_FOG_MODE; + fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT;/*JJJ*/ } if ( fxMesa->Fog.Color != color ) { fxMesa->Fog.Color = color; @@ -569,6 +571,26 @@ static void tdfxDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_FOG; + + switch (pname) { + case GL_FOG_COORDINATE_SOURCE_EXT: { + GLenum p = (GLenum)*param; + if (p == GL_FOG_COORDINATE_EXT) { + _swrast_allow_vertex_fog(ctx, GL_TRUE); + _swrast_allow_pixel_fog(ctx, GL_FALSE); + _tnl_allow_vertex_fog( ctx, GL_TRUE); + _tnl_allow_pixel_fog( ctx, GL_FALSE); + } else { + _swrast_allow_vertex_fog(ctx, GL_FALSE); + _swrast_allow_pixel_fog(ctx, GL_TRUE); + _tnl_allow_vertex_fog( ctx, GL_FALSE); + _tnl_allow_pixel_fog( ctx, GL_TRUE); + } + break; + } + default: + ; + } } @@ -912,7 +934,7 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) fxMesa->new_state |= TDFX_NEW_ALPHA; FALLBACK( fxMesa, TDFX_FALLBACK_LOGICOP, (ctx->Color.ColorLogicOpEnabled && - ctx->Color.LogicOp != GL_COPY)); + ctx->Color.LogicOp != GL_COPY)/*JJJ - more blending*/); break; case GL_CULL_FACE: @@ -974,15 +996,16 @@ static void tdfxDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) case GL_STENCIL_TEST: FLUSH_BATCH( fxMesa ); FALLBACK( fxMesa, TDFX_FALLBACK_STENCIL, state && !fxMesa->haveHwStencil); + fxMesa->new_state |= TDFX_NEW_STENCIL; break; - case GL_TEXTURE_1D: case GL_TEXTURE_3D: FLUSH_BATCH( fxMesa ); - FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_1D_3D, state); /* wrong */ + FALLBACK( fxMesa, TDFX_FALLBACK_TEXTURE_MAP, state); /* wrong */ fxMesa->new_state |= TDFX_NEW_TEXTURE; break; + case GL_TEXTURE_1D: case GL_TEXTURE_2D: FLUSH_BATCH( fxMesa ); fxMesa->new_state |= TDFX_NEW_TEXTURE; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c index f9d6c2a6577..ebb06b1d357 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tex.c,v 1.7 2002/11/05 17:46:10 tsi Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -36,6 +39,7 @@ */ #include "image.h" +#include "texcompress.h" #include "texformat.h" #include "teximage.h" #include "texstore.h" @@ -45,6 +49,55 @@ #include "tdfx_texman.h" +void +_mesa_halve2x2_teximage2d ( GLuint bytesPerPixel, + GLint srcWidth, GLint srcHeight, + const GLvoid *srcImage, GLvoid *dstImage ) +{ + GLint i, j, k; + const GLint dstWidth = srcWidth / 2; + const GLint dstHeight = srcHeight / 2; + const GLint srcRowStride = srcWidth * bytesPerPixel; + const GLubyte *src = srcImage; + GLubyte *dst = dstImage; + + /* no borders! can't halve 1x1! (stride > width * comp) not allowed */ + if (srcHeight == 1) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[bytesPerPixel] + 1) / 2; + src++; + dst++; + } + src += bytesPerPixel; + } + } else if (srcWidth == 1) { + for (j = 0; j < dstHeight; j++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + src[srcRowStride] + 1) / 2; + src++; + dst++; + } + src += srcRowStride; + } + } else { + for (j = 0; j < dstHeight; j++) { + for (i = 0; i < dstWidth; i++) { + for (k = 0; k < bytesPerPixel; k++) { + dst[0] = (src[0] + + src[bytesPerPixel] + + src[srcRowStride] + + src[srcRowStride + bytesPerPixel] + 2) / 4; + src++; + dst++; + } + src += bytesPerPixel; + } + src += srcRowStride; + } + } +} + static int logbase2(int n) @@ -102,45 +155,38 @@ tdfxTexGetInfo(const GLcontext *ctx, int w, int h, logw = logbase2(w); logh = logbase2(h); ar = logw - logh; /* aspect ratio = difference in log dimensions */ + s = t = 256.0; + ws = hs = 1; /* Hardware only allows a maximum aspect ratio of 8x1, so handle |ar| > 3 by scaling the image and using an 8x1 aspect ratio */ if (ar >= 0) { ASSERT(width >= height); lod = logw; - s = 256.0; - ws = 1; if (ar <= GR_ASPECT_LOG2_8x1) { t = 256 >> ar; - hs = 1; } else { /* have to stretch image height */ t = 32.0; hs = 1 << (ar - 3); + ar = GR_ASPECT_LOG2_8x1; } } else { ASSERT(width < height); lod = logh; - t = 256.0; - hs = 1; if (ar >= GR_ASPECT_LOG2_1x8) { s = 256 >> -ar; - ws = 1; } else { /* have to stretch image width */ s = 32.0; ws = 1 << (-ar - 3); + ar = GR_ASPECT_LOG2_1x8; } } - if (ar < GR_ASPECT_LOG2_1x8) - ar = GR_ASPECT_LOG2_1x8; - else if (ar > GR_ASPECT_LOG2_8x1) - ar = GR_ASPECT_LOG2_8x1; - if (lodlevel) *lodlevel = (GrLOD_t) lod; if (aspectratio) @@ -196,6 +242,16 @@ static void RevalidateTexture(GLcontext *ctx, struct gl_texture_object *tObj) ti->minLevel = minl; ti->maxLevel = maxl; ti->info.data = NULL; + + /* this is necessary because of fxDDCompressedTexImage2D */ + if (ti->padded) { + struct gl_texture_image *texImage = tObj->Image[0][minl]; + tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + if (mml->wScale != 1 || mml->hScale != 1) { + ti->sScale /= mml->wScale; + ti->tScale /= mml->hScale; + } + } } @@ -244,7 +300,7 @@ tdfxBindTexture(GLcontext * ctx, GLenum target, tObj->DriverData); } - if (target != GL_TEXTURE_2D) + if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D)) return; if (!tObj->DriverData) { @@ -301,7 +357,7 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, tObj->DriverData, pname, param); } - if (target != GL_TEXTURE_2D) + if ((target != GL_TEXTURE_1D) && (target != GL_TEXTURE_2D)) return; if (!tObj->DriverData) @@ -323,7 +379,7 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, ti->LODblend = FXFALSE; break; case GL_NEAREST_MIPMAP_LINEAR: - if (TDFX_IS_NAPALM(fxMesa)) { + if (!fxMesa->Glide.HaveCombineExt) { if (fxMesa->haveTwoTMUs) { ti->mmMode = GR_MIPMAP_NEAREST; ti->LODblend = FXTRUE; @@ -345,7 +401,7 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, ti->LODblend = FXFALSE; break; case GL_LINEAR_MIPMAP_LINEAR: - if (TDFX_IS_NAPALM(fxMesa)) { + if (!fxMesa->Glide.HaveCombineExt) { if (fxMesa->haveTwoTMUs) { ti->mmMode = GR_MIPMAP_NEAREST; ti->LODblend = FXTRUE; @@ -369,6 +425,7 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, default: break; } + ti->reloadImages = GL_TRUE; RevalidateTexture(ctx, tObj); fxMesa->new_state |= TDFX_NEW_TEXTURE; break; @@ -389,12 +446,17 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, case GL_TEXTURE_WRAP_S: switch (param) { + case GL_CLAMP_TO_BORDER: + case GL_CLAMP_TO_EDGE: case GL_CLAMP: ti->sClamp = GR_TEXTURECLAMP_CLAMP; break; case GL_REPEAT: ti->sClamp = GR_TEXTURECLAMP_WRAP; break; + case GL_MIRRORED_REPEAT: + ti->sClamp = GR_TEXTURECLAMP_MIRROR_EXT; + break; default: break; } @@ -403,12 +465,17 @@ tdfxTexParameter(GLcontext * ctx, GLenum target, case GL_TEXTURE_WRAP_T: switch (param) { + case GL_CLAMP_TO_BORDER: + case GL_CLAMP_TO_EDGE: case GL_CLAMP: ti->tClamp = GR_TEXTURECLAMP_CLAMP; break; case GL_REPEAT: ti->tClamp = GR_TEXTURECLAMP_WRAP; break; + case GL_MIRRORED_REPEAT: + ti->tClamp = GR_TEXTURECLAMP_MIRROR_EXT; + break; default: break; } @@ -469,7 +536,7 @@ tdfxIsTextureResident(GLcontext *ctx, struct gl_texture_object *tObj) /* * Convert a gl_color_table texture palette to Glide's format. */ -static void +static GrTexTable_t convertPalette(FxU32 data[256], const struct gl_color_table *table) { const GLubyte *tableUB = (const GLubyte *) table->Table; @@ -488,7 +555,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE_6666_EXT; case GL_LUMINANCE: for (i = 0; i < width; i++) { r = tableUB[i]; @@ -497,21 +564,21 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE; case GL_ALPHA: for (i = 0; i < width; i++) { r = g = b = 255; a = tableUB[i]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE_6666_EXT; case GL_LUMINANCE_ALPHA: for (i = 0; i < width; i++) { r = g = b = tableUB[i * 2 + 0]; a = tableUB[i * 2 + 1]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE_6666_EXT; case GL_RGB: for (i = 0; i < width; i++) { r = tableUB[i * 3 + 0]; @@ -520,7 +587,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = 255; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE; case GL_RGBA: for (i = 0; i < width; i++) { r = tableUB[i * 4 + 0]; @@ -529,7 +596,7 @@ convertPalette(FxU32 data[256], const struct gl_color_table *table) a = tableUB[i * 4 + 3]; data[i] = (a << 24) | (r << 16) | (g << 8) | b; } - break; + return GR_TEXTABLE_PALETTE_6666_EXT; } } @@ -552,12 +619,14 @@ tdfxUpdateTexturePalette(GLcontext * ctx, struct gl_texture_object *tObj) tObj->DriverData = fxAllocTexObjData(fxMesa); ti = TDFX_TEXTURE_DATA(tObj); assert(ti); - convertPalette(ti->palette.data, &tObj->Palette); + ti->paltype = convertPalette(ti->palette.data, &tObj->Palette); /*tdfxTexInvalidate(ctx, tObj);*/ } else { /* global texture palette */ - convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->TexPalette.Type = convertPalette(fxMesa->glbPalette.data, &ctx->Texture.Palette); + fxMesa->TexPalette.Data = &(fxMesa->glbPalette.data); + fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX too heavy-handed */ } @@ -599,6 +668,7 @@ tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: return &_mesa_texformat_a8; case 1: case GL_LUMINANCE: @@ -606,6 +676,7 @@ tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: return &_mesa_texformat_l8; case 2: case GL_LUMINANCE_ALPHA: @@ -615,31 +686,52 @@ tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: return &_mesa_texformat_al88; case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: return &_mesa_texformat_i8; case GL_R3_G3_B2: case GL_RGB4: case GL_RGB5: return &_mesa_texformat_rgb565; + case GL_COMPRESSED_RGB: + /* intentional fall-through */ case 3: case GL_RGB: + if ( srcFormat == GL_RGB && srcType == GL_UNSIGNED_SHORT_5_6_5 ) { + return &_mesa_texformat_rgb565; + } + /* intentional fall through */ case GL_RGB8: case GL_RGB10: case GL_RGB12: case GL_RGB16: return (allow32bpt) ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; - break; case GL_RGBA2: case GL_RGBA4: return &_mesa_texformat_argb4444; + case GL_COMPRESSED_RGBA: + /* intentional fall-through */ case 4: case GL_RGBA: + if ( srcFormat == GL_BGRA ) { + if ( srcType == GL_UNSIGNED_INT_8_8_8_8_REV ) { + return &_mesa_texformat_argb8888; + } + else if ( srcType == GL_UNSIGNED_SHORT_4_4_4_4_REV ) { + return &_mesa_texformat_argb4444; + } + else if ( srcType == GL_UNSIGNED_SHORT_1_5_5_5_REV ) { + return &_mesa_texformat_argb1555; + } + } + /* intentional fall through */ case GL_RGBA8: case GL_RGB10_A2: case GL_RGBA12: @@ -656,6 +748,25 @@ tdfxChooseTextureFormat( GLcontext *ctx, GLint internalFormat, case GL_COLOR_INDEX12_EXT: case GL_COLOR_INDEX16_EXT: return &_mesa_texformat_ci8; + /* GL_EXT_texture_compression_s3tc */ + /* GL_S3_s3tc */ + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + return &_mesa_texformat_rgb_dxt1; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return &_mesa_texformat_rgba_dxt1; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + return &_mesa_texformat_rgba_dxt3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + return &_mesa_texformat_rgba_dxt5; + /* GL_3DFX_texture_compression_FXT1 */ + case GL_COMPRESSED_RGB_FXT1_3DFX: + return &_mesa_texformat_rgb_fxt1; + case GL_COMPRESSED_RGBA_FXT1_3DFX: + return &_mesa_texformat_rgba_fxt1; default: _mesa_problem(ctx, "unexpected format in tdfxChooseTextureFormat"); return NULL; @@ -688,6 +799,16 @@ fxGlideFormat(GLint mesaFormat) return GR_TEXFMT_ARGB_1555; case MESA_FORMAT_ARGB8888: return GR_TEXFMT_ARGB_8888; + case MESA_FORMAT_RGB_FXT1: + case MESA_FORMAT_RGBA_FXT1: + return GR_TEXFMT_ARGB_CMP_FXT1; + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_RGBA_DXT1: + return GR_TEXFMT_ARGB_CMP_DXT1; + case MESA_FORMAT_RGBA_DXT3: + return GR_TEXFMT_ARGB_CMP_DXT3; + case MESA_FORMAT_RGBA_DXT5: + return GR_TEXFMT_ARGB_CMP_DXT5; default: _mesa_problem(NULL, "Unexpected format in fxGlideFormat"); return 0; @@ -701,6 +822,9 @@ fxGlideFormat(GLint mesaFormat) * images on tdfx hardware (the 8:1 aspect ratio limit). * Hence, we need special functions here. */ +extern void +fxt1_decode_1 (const void *texture, int width, + int i, int j, unsigned char *rgba); static void fetch_intensity8(const struct gl_texture_image *texImage, @@ -747,8 +871,6 @@ fetch_alpha8(const struct gl_texture_image *texImage, i = i * mml->wScale; j = j * mml->hScale; - i = i * mml->width / texImage->Width; - j = j * mml->height / texImage->Height; texel = ((GLubyte *) texImage->Data) + j * mml->width + i; rgba[RCOMP] = 255; @@ -760,11 +882,16 @@ fetch_alpha8(const struct gl_texture_image *texImage, static void fetch_index8(const struct gl_texture_image *texImage, - GLint i, GLint j, GLint k, GLchan * rgba) + GLint i, GLint j, GLint k, GLchan * indexOut) { const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); - (void) mml; - /* XXX todo */ + const GLubyte *texel; + + i = i * mml->wScale; + j = j * mml->hScale; + + texel = ((GLubyte *) texImage->Data) + j * mml->width + i; + *indexOut = *texel; } @@ -858,36 +985,206 @@ fetch_a8r8g8b8(const struct gl_texture_image *texImage, } +static void +fetch_rgb_fxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + fxt1_decode_1(texImage->Data, mml->width, i, j, rgba); + rgba[ACOMP] = 255; +} + + +static void +fetch_rgba_fxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + fxt1_decode_1(texImage->Data, mml->width, i, j, rgba); +} + + +static void +fetch_rgb_dxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgb_dxt1.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt1(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt1.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt3(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt3.FetchTexel2D(texImage, i, j, k, rgba); +} + + +static void +fetch_rgba_dxt5(const struct gl_texture_image *texImage, + GLint i, GLint j, GLint k, GLchan *rgba) +{ + const tdfxMipMapLevel *mml = TDFX_TEXIMAGE_DATA(texImage); + + i = i * mml->wScale; + j = j * mml->hScale; + + _mesa_texformat_rgba_dxt5.FetchTexel2D(texImage, i, j, k, rgba); +} + + static FetchTexelFuncC fxFetchFunction(GLint mesaFormat) { switch (mesaFormat) { case MESA_FORMAT_I8: - return fetch_intensity8; + return &fetch_intensity8; case MESA_FORMAT_A8: - return fetch_alpha8; + return &fetch_alpha8; case MESA_FORMAT_L8: - return fetch_luminance8; + return &fetch_luminance8; case MESA_FORMAT_CI8: - return fetch_index8; + return &fetch_index8; case MESA_FORMAT_AL88: - return fetch_luminance8_alpha8; + return &fetch_luminance8_alpha8; case MESA_FORMAT_RGB565: - return fetch_r5g6b5; + return &fetch_r5g6b5; case MESA_FORMAT_ARGB4444: - return fetch_r4g4b4a4; + return &fetch_r4g4b4a4; case MESA_FORMAT_ARGB1555: - return fetch_r5g5b5a1; + return &fetch_r5g5b5a1; case MESA_FORMAT_ARGB8888: - return fetch_a8r8g8b8; + return &fetch_a8r8g8b8; + case MESA_FORMAT_RGB_FXT1: + return &fetch_rgb_fxt1; + case MESA_FORMAT_RGBA_FXT1: + return &fetch_rgba_fxt1; + case MESA_FORMAT_RGB_DXT1: + return &fetch_rgb_dxt1; + case MESA_FORMAT_RGBA_DXT1: + return &fetch_rgba_dxt1; + case MESA_FORMAT_RGBA_DXT3: + return &fetch_rgba_dxt3; + case MESA_FORMAT_RGBA_DXT5: + return &fetch_rgba_dxt5; default: _mesa_problem(NULL, "Unexpected format in fxFetchFunction"); - printf("%d\n", mesaFormat); return NULL; } } +static GLboolean +adjust2DRatio (GLcontext *ctx, + GLint xoffset, GLint yoffset, + GLint width, GLint height, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + tdfxMipMapLevel *mml, + struct gl_texture_image *texImage, + GLint texelBytes, + GLint dstRowStride) +{ + const GLint newWidth = width * mml->wScale; + const GLint newHeight = height * mml->hScale; + GLvoid *tempImage; + + if (!texImage->IsCompressed) { + GLubyte *destAddr; + tempImage = MALLOC(width * height * texelBytes); + if (!tempImage) { + return GL_FALSE; + } + + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, tempImage, + 0, 0, 0, /* dstX/Y/Zoffset */ + width * texelBytes, /* dstRowStride */ + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + + /* now rescale */ + /* compute address of dest subimage within the overal tex image */ + destAddr = (GLubyte *) texImage->Data + + (yoffset * mml->hScale * mml->width + + xoffset * mml->wScale) * texelBytes; + + _mesa_rescale_teximage2d(texelBytes, + dstRowStride, /* dst stride */ + width, height, + newWidth, newHeight, + tempImage, destAddr); + } else { + const GLint rawBytes = 4; + GLvoid *rawImage = MALLOC(width * height * rawBytes); + if (!rawImage) { + return GL_FALSE; + } + tempImage = MALLOC(newWidth * newHeight * rawBytes); + if (!tempImage) { + return GL_FALSE; + } + /* unpack image, apply transfer ops and store in rawImage */ + _mesa_texstore_rgba8888(ctx, 2, GL_RGBA, + &_mesa_texformat_rgba8888_rev, rawImage, + 0, 0, 0, /* dstX/Y/Zoffset */ + width * rawBytes, /* dstRowStride */ + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + _mesa_rescale_teximage2d(rawBytes, + newWidth * rawBytes, /* dst stride */ + width, height, /* src */ + newWidth, newHeight, /* dst */ + rawImage /*src*/, tempImage /*dst*/ ); + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + xoffset * mml->wScale, yoffset * mml->hScale, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + newWidth, newHeight, 1, + GL_RGBA, CHAN_TYPE, tempImage, &ctx->DefaultPacking); + FREE(rawImage); + } + + FREE(tempImage); + + return GL_TRUE; +} + + static void tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, GLint internalFormat, GLint width, GLint height, GLint border, @@ -899,7 +1196,7 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; - GLint texelBytes; + GLint texelBytes, dstRowStride; /* printf("TexImage id=%d int 0x%x format 0x%x type 0x%x %dx%d\n", @@ -942,6 +1239,45 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, mml->width = width * mml->wScale; mml->height = height * mml->hScale; +#if FX_COMPRESS_S3TC_AS_FXT1_HACK + /* [koolsmoky] substitute FXT1 for DXTn and Legacy S3TC */ + /* [dBorca] we should update texture's attribute, then, + * because if the application asks us to decompress, we + * have to know the REAL format! Also, DXT3/5 might not + * be correct, since it would mess with "compressedSize". + * Ditto for GL_RGBA[4]_S3TC, which is always mapped to DXT3. + */ + if (texImage->IsCompressed) { + switch (internalFormat) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_RGB_S3TC: + case GL_RGB4_S3TC: + internalFormat = GL_COMPRESSED_RGB_FXT1_3DFX; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_RGBA_S3TC: + case GL_RGBA4_S3TC: + internalFormat = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + texImage->IntFormat = internalFormat; + } +#endif +#if FX_TC_NAPALM + if (fxMesa->type >= GR_SSTTYPE_Voodoo4) { + GLenum texNapalm = 0; + if (internalFormat == GL_COMPRESSED_RGB) { + texNapalm = GL_COMPRESSED_RGB_FXT1_3DFX; + } else if (internalFormat == GL_COMPRESSED_RGBA) { + texNapalm = GL_COMPRESSED_RGBA_FXT1_3DFX; + } + if (texNapalm) { + texImage->IntFormat = internalFormat = texNapalm; + texImage->IsCompressed = GL_TRUE; + } + } +#endif /* choose the texture format */ assert(ctx->Driver.ChooseTextureFormat); @@ -953,58 +1289,88 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level, texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); texelBytes = texImage->TexFormat->TexelBytes; - if (mml->width != width || mml->height != height) { - /* rescale the image to overcome 1:8 aspect limitation */ - GLvoid *tempImage; - /* allocate temporary image */ - tempImage = MALLOC(width * height * texelBytes); - if (!tempImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - /* allocate texture memory */ - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - FREE(tempImage); - return; - } - if (pixels) { - /* unpack image, apply transfer ops and store in tempImage */ - texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, - texImage->TexFormat, tempImage, - 0, 0, 0, /* dstX/Y/Zoffset */ - width * texelBytes, /* dstRowStride */ - 0, /* dstImageStride */ - width, height, 1, - format, type, pixels, packing); - /* rescale */ - _mesa_rescale_teximage2d(texelBytes, - mml->width * texelBytes, /* dst stride */ - width, height, - mml->width, mml->height, - tempImage /*src*/, texImage->Data /*dst*/ ); - } - FREE(tempImage); + if (texImage->IsCompressed) { + texImage->CompressedSize = _mesa_compressed_texture_size(ctx, + mml->width, + mml->height, + 1, + internalFormat); + dstRowStride = _mesa_compressed_row_stride(internalFormat, mml->width); + texImage->Data = MESA_PBUFFER_ALLOC(texImage->CompressedSize); + } else { + dstRowStride = mml->width * texelBytes; + texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); } - else { - /* no rescaling needed */ - assert(!texImage->Data); - texImage->Data = MESA_PBUFFER_ALLOC(mml->width * mml->height * texelBytes); - if (!texImage->Data) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); - return; - } - /* unpack image, apply transfer ops and store in texImage->Data */ - if (pixels) { - texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, - texImage->TexFormat, texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - width * texelBytes, /* dstRowStride */ - 0, /* dstImageStride */ - width, height, 1, - format, type, pixels, packing); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + + if (pixels != NULL) { + if (mml->wScale != 1 || mml->hScale != 1) { + /* rescale image to overcome 1:8 aspect limitation */ + if (!adjust2DRatio(ctx, + 0, 0, + width, height, + format, type, pixels, + packing, + mml, + texImage, + texelBytes, + dstRowStride) + ) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + else { + /* no rescaling needed */ + /* unpack image, apply transfer ops and store in texImage->Data */ + texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, + texImage->TexFormat, texImage->Data, + 0, 0, 0, /* dstX/Y/Zoffset */ + dstRowStride, + 0, /* dstImageStride */ + width, height, 1, + format, type, pixels, packing); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tdfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + _mesa_TexImage2D(target, ++level, internalFormat, + mipWidth, mipHeight, border, + format, type, + NULL); + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = TDFX_TEXIMAGE_DATA(mipImage); + _mesa_halve2x2_teximage2d(texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } } } @@ -1028,7 +1394,7 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; - GLint texelBytes; + GLint texelBytes, dstRowStride; if (!texObj->DriverData) { _mesa_problem(ctx, "problem in fxDDTexSubImage2D"); @@ -1044,201 +1410,309 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level, assert(texImage->Format); texelBytes = texImage->TexFormat->TexelBytes; + if (texImage->IsCompressed) { + dstRowStride = _mesa_compressed_row_stride(texImage->IntFormat, mml->width); + } else { + dstRowStride = mml->width * texelBytes; + } if (mml->wScale != 1 || mml->hScale != 1) { - /* need to rescale subimage to match mipmap level's rescale factors */ - const GLint newWidth = width * mml->wScale; - const GLint newHeight = height * mml->hScale; - GLvoid *scaledImage, *tempImage; - GLubyte *destAddr; - tempImage = MALLOC(width * height * texelBytes); - if (!tempImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - return; - } - - texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, - texImage->TexFormat, texImage->Data, - 0, 0, 0, /* dstX/Y/Zoffset */ - width * texelBytes, /* dstRowStride */ - 0, /* dstImageStride */ - width, height, 1, - format, type, pixels, packing); - - /* now rescale */ - scaledImage = MALLOC(newWidth * newHeight * texelBytes); - if (!scaledImage) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); - FREE(tempImage); - return; - } - - /* compute address of dest subimage within the overal tex image */ - destAddr = (GLubyte *) texImage->Data - + (yoffset * mml->hScale * mml->width - + xoffset * mml->wScale) * texelBytes; - - _mesa_rescale_teximage2d(texelBytes, - mml->width * texelBytes, /* dst stride */ - width, height, - newWidth, newHeight, - tempImage, destAddr); - - FREE(tempImage); - FREE(scaledImage); + /* need to rescale subimage to match mipmap level's rescale factors */ + if (!adjust2DRatio(ctx, + xoffset, yoffset, + width, height, + format, type, pixels, + packing, + mml, + texImage, + texelBytes, + dstRowStride) + ) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage2D"); + return; + } } else { /* no rescaling needed */ texImage->TexFormat->StoreImage(ctx, 2, texImage->Format, texImage->TexFormat, texImage->Data, xoffset, yoffset, 0, - mml->width * texelBytes, /* dstRowStride */ + dstRowStride, 0, /* dstImageStride */ width, height, 1, format, type, pixels, packing); } + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + GLint mipWidth, mipHeight; + tdfxMipMapLevel *mip; + struct gl_texture_image *mipImage; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target); + + assert(!texImage->IsCompressed); + + width = texImage->Width; + height = texImage->Height; + while (level < texObj->MaxLevel && level < maxLevels - 1) { + mipWidth = width / 2; + if (!mipWidth) { + mipWidth = 1; + } + mipHeight = height / 2; + if (!mipHeight) { + mipHeight = 1; + } + if ((mipWidth == width) && (mipHeight == height)) { + break; + } + ++level; + mipImage = _mesa_select_tex_image(ctx, texUnit, target, level); + mip = TDFX_TEXIMAGE_DATA(mipImage); + _mesa_halve2x2_teximage2d(texelBytes, + mml->width, mml->height, + texImage->Data, mipImage->Data); + texImage = mipImage; + mml = mip; + width = mipWidth; + height = mipHeight; + } + } + ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */ fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */ } +static void +tdfxTexImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) +{ + tdfxTexImage2D(ctx, target, level, + internalFormat, width, 1, border, + format, type, pixels, + packing, + texObj, + texImage); +} + +static void +tdfxTexSubImage1D(GLcontext *ctx, GLenum target, GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + tdfxTexSubImage2D(ctx, target, level, + xoffset, 0, + width, 1, + format, type, + pixels, + packing, + texObj, + texImage); +} /**********************************************************************/ /**** COMPRESSED TEXTURE IMAGE FUNCTIONS ****/ /**********************************************************************/ -#if 0000 -GLboolean -tdfxCompressedTexImage2D( GLcontext *ctx, GLenum target, - GLint level, GLsizei imageSize, - const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLboolean *retainInternalCopy) +static void +tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target, + GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - const GLboolean allow32bpt = TDFX_IS_NAPALM(fxMesa); - GrTextureFormat_t gldformat; tdfxTexInfo *ti; tdfxMipMapLevel *mml; - GLint dstWidth, dstHeight, wScale, hScale, texelSize; - MesaIntTexFormat intFormat; - GLboolean isCompressedFormat; - GLsizei texSize; - if (target != GL_TEXTURE_2D || texImage->Border > 0) - return GL_FALSE; + if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { + fprintf(stderr, "tdfxCompressedTexImage2D: id=%d int 0x%x %dx%d\n", + texObj->Name, internalFormat, + width, height); + } + + if ((target != GL_TEXTURE_1D && target != GL_TEXTURE_2D) || texImage->Border > 0) { + _mesa_problem(NULL, "tdfx: unsupported texture in tdfxCompressedTexImg()\n"); + return; + } + + assert(texImage->IsCompressed); ti = TDFX_TEXTURE_DATA(texObj); + if (!ti) { + texObj->DriverData = fxAllocTexObjData(fxMesa); + if (!texObj->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + ti = TDFX_TEXTURE_DATA(texObj); + } assert(ti); - mml = &ti->mipmapLevel[level]; - isCompressedFormat = tdfxDDIsCompressedGlideFormatMacro(texImage->IntFormat); - if (!isCompressedFormat) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage2D(format)"); - return GL_FALSE; + mml = TDFX_TEXIMAGE_DATA(texImage); + if (!mml) { + texImage->DriverData = CALLOC(sizeof(tdfxMipMapLevel)); + if (!texImage->DriverData) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } + mml = TDFX_TEXIMAGE_DATA(texImage); } - /* Determine the apporpriate GL internal texel format, Mesa internal - * texel format, and texelSize (bytes) given the user's internal - * texture format hint. - */ - tdfxTexGetFormat(texImage->IntFormat, allow32bpt, - &gldformat, &intFormat, &texelSize); - /* Determine width and height scale factors for texture. - * Remember, Glide is limited to 8:1 aspect ratios. + tdfxTexGetInfo(ctx, width, height, NULL, NULL, NULL, NULL, + &mml->wScale, &mml->hScale); + + mml->width = width * mml->wScale; + mml->height = height * mml->hScale; + + + /* choose the texture format */ + assert(ctx->Driver.ChooseTextureFormat); + texImage->TexFormat = (*ctx->Driver.ChooseTextureFormat)(ctx, + internalFormat, -1/*format*/, -1/*type*/); + assert(texImage->TexFormat); + + /* Determine the appropriate Glide texel format, + * given the user's internal texture format hint. */ - tdfxTexGetInfo(ctx, - texImage->Width, texImage->Height, - NULL, /* lod level */ - NULL, /* aspect ratio */ - NULL, NULL, /* sscale, tscale */ - &wScale, &hScale); - dstWidth = texImage->Width * wScale; - dstHeight = texImage->Height * hScale; - /* housekeeping */ - _mesa_set_teximage_component_sizes(intFormat, texImage); - - texSize = tdfxDDCompressedImageSize(ctx, - texImage->IntFormat, - 2, - texImage->Width, - texImage->Height, - 1); - if (texSize != imageSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage2D(texSize)"); - return GL_FALSE; - } + mml->glideFormat = fxGlideFormat(texImage->TexFormat->MesaFormat); + ti->info.format = mml->glideFormat; + texImage->FetchTexelc = fxFetchFunction(texImage->TexFormat->MesaFormat); /* allocate new storage for texture image, if needed */ - if (!mml->data || mml->glideFormat != gldformat || - mml->width != dstWidth || mml->height != dstHeight || - texSize != mml->dataSize) { - if (mml->data) { - FREE(mml->data); - } - mml->data = MALLOC(texSize); - if (!mml->data) { - return GL_FALSE; - } - mml->texelSize = texelSize; - mml->glideFormat = gldformat; - mml->width = dstWidth; - mml->height = dstHeight; - tdfxTMMoveOutTM(fxMesa, texObj); - /*tdfxTexInvalidate(ctx, texObj);*/ + if (!texImage->Data) { + texImage->CompressedSize = _mesa_compressed_texture_size(ctx, + mml->width, + mml->height, + 1, + internalFormat); + texImage->Data = MESA_PBUFFER_ALLOC(texImage->CompressedSize); + if (!texImage->Data) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D"); + return; + } } /* save the texture data */ - MEMCPY(mml->data, data, imageSize); + if (mml->wScale != 1 || mml->hScale != 1) { + /* [dBorca] Hack alert: + * now we're screwed. We can't decompress, + * unless we do it in HW (via textureBuffer). + * We still have some chances: + * 1) we got FXT1 textures - we CAN decompress, rescale for + * aspectratio, then compress back. + * 2) there is a chance that MIN("s", "t") won't be overflowed. + * Thus, we don't care about textureclamp and we could lower + * MIN("uscale", "vscale") below 32. We still have to have + * our data aligned inside a 8:1 rectangle. + * 3) just in case if MIN("s", "t") gets overflowed with GL_REPEAT, + * we replicate the data over the padded area. + * For now, we take 2) + 3) but texelfetchers will be wrong! + */ + GLuint srcRowStride = _mesa_compressed_row_stride(internalFormat, width); + + GLuint destRowStride = _mesa_compressed_row_stride(internalFormat, + mml->width); + + _mesa_upscale_teximage2d(srcRowStride, (height+3) / 4, + destRowStride, (mml->height+3) / 4, + 1, data, srcRowStride, + texImage->Data); + ti->padded = GL_TRUE; + } else { + MEMCPY(texImage->Data, data, texImage->CompressedSize); + } + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + assert(!texImage->IsCompressed); + } RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; fxMesa->new_state |= TDFX_NEW_TEXTURE; - - *retainInternalCopy = GL_FALSE; - return GL_TRUE; } -GLboolean + +static void tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLint height, GLenum format, - GLsizei imageSize, const GLvoid *data, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) + GLint level, GLint xoffset, + GLint yoffset, GLsizei width, + GLint height, GLenum format, + GLsizei imageSize, const GLvoid *data, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); tdfxTexInfo *ti; tdfxMipMapLevel *mml; + GLint destRowStride, srcRowStride; + GLint i, rows; + GLubyte *dest; - /* - * We punt if we are not replacing the entire image. This - * is allowed by the spec. - */ - if ((xoffset != 0) && (yoffset != 0) - && (width != texImage->Width) - && (height != texImage->Height)) { - return GL_FALSE; + if (TDFX_DEBUG & DEBUG_VERBOSE_DRI) { + fprintf(stderr, "tdfxCompressedTexSubImage2D: id=%d\n", texObj->Name); } ti = TDFX_TEXTURE_DATA(texObj); - mml = &ti->mipmapLevel[level]; - if (imageSize != mml->dataSize) { - return GL_FALSE; + assert(ti); + mml = TDFX_TEXIMAGE_DATA(texImage); + assert(mml); + + srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, width); + + destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + mml->width); + dest = _mesa_compressed_image_address(xoffset, yoffset, 0, + texImage->IntFormat, + mml->width, + (GLubyte*) texImage->Data); + + rows = height / 4; /* [dBorca] hardcoded 4, but works for FXT1/DXTC */ + + for (i = 0; i < rows; i++) { + MEMCPY(dest, data, srcRowStride); + dest += destRowStride; + data = (GLvoid *)((GLuint)data + (GLuint)srcRowStride); + } + + /* [dBorca] Hack alert: + * see fxDDCompressedTexImage2D for caveats + */ + if (mml->wScale != 1 || mml->hScale != 1) { + srcRowStride = _mesa_compressed_row_stride(texImage->IntFormat, texImage->Width); + + destRowStride = _mesa_compressed_row_stride(texImage->IntFormat, + mml->width); + _mesa_upscale_teximage2d(srcRowStride, texImage->Height / 4, + destRowStride, mml->height / 4, + 1, texImage->Data, destRowStride, + texImage->Data); } - MEMCPY(data, mml->data, imageSize); + + /* GL_SGIS_generate_mipmap */ + if (level == texObj->BaseLevel && texObj->GenerateMipmap) { + assert(!texImage->IsCompressed); + } + + RevalidateTexture(ctx, texObj); ti->reloadImages = GL_TRUE; fxMesa->new_state |= TDFX_NEW_TEXTURE; - - return GL_TRUE; } -#endif - #if 0 @@ -1273,7 +1747,7 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target, switch (target) { case GL_PROXY_TEXTURE_1D: - return GL_TRUE; /* software rendering */ + /*JJJ wrong*/ case GL_PROXY_TEXTURE_2D: { struct gl_texture_object *tObj; @@ -1340,141 +1814,6 @@ tdfxTestProxyTexImage(GLcontext *ctx, GLenum target, } -#if 000 -/* - * This is called from _mesa_GetCompressedTexImage. We just - * copy out the compressed data. - */ -void -tdfxGetCompressedTexImage( GLcontext *ctx, GLenum target, - GLint lod, void *image, - const struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - tdfxTexInfo *ti; - tdfxMipMapLevel *mml; - - if (target != GL_TEXTURE_2D) - return; - - if (!texObj->DriverData) - return; - - ti = TDFX_TEXTURE_DATA(texObj); - assert(ti); - mml = &ti->mipmapLevel[lod]; - if (mml->data) { - MEMCPY(image, mml->data, mml->dataSize); - } -} -#endif - -/* - * Calculate a specific texture format given a generic - * texture format. - */ -GLint -tdfxSpecificCompressedTexFormat(GLcontext *ctx, - GLint internalFormat, - GLint numDimensions) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - - if (numDimensions != 2) { - return internalFormat; - } - /* - * If we don't have pointers to the functions, then - * we drop back to uncompressed format. The logic - * in Mesa proper handles this for us. - * - * This is just to ease the transition to a Glide with - * the texus2 library. - */ - if (!fxMesa->Glide.txImgQuantize || !fxMesa->Glide.txImgDequantizeFXT1) { - return internalFormat; - } - switch (internalFormat) { - case GL_COMPRESSED_RGB_ARB: - return GL_COMPRESSED_RGB_FXT1_3DFX; - case GL_COMPRESSED_RGBA_ARB: - return GL_COMPRESSED_RGBA_FXT1_3DFX; - } - return internalFormat; -} - -/* - * Calculate a specific texture format given a generic - * texture format. - */ -GLint -tdfxBaseCompressedTexFormat(GLcontext *ctx, - GLint internalFormat) -{ - switch (internalFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - return GL_RGB; - case GL_COMPRESSED_RGBA_FXT1_3DFX: - return GL_RGBA; - } - return -1; -} - -/* - * Tell us if an image is compressed. The real work is done - * in a macro, but we need to have a function to create a - * function pointer. - */ -GLboolean -tdfxDDIsCompressedFormat(GLcontext *ctx, GLint internalFormat) -{ - return tdfxDDIsCompressedFormatMacro(internalFormat); -} - - -/* - * Calculate the image size of a compressed texture. - * - * The current compressed format, the FXT1 family, all - * map 8x32 texel blocks into 128 bits. - * - * We return 0 if we can't calculate the size. - * - * Glide would report this out to us, but we don't have - * exactly the right parameters. - */ -GLsizei -tdfxDDCompressedImageSize(GLcontext *ctx, - GLenum intFormat, - GLuint numDimensions, - GLuint width, - GLuint height, - GLuint depth) -{ - if (numDimensions != 2) { - return 0; - } - switch (intFormat) { - case GL_COMPRESSED_RGB_FXT1_3DFX: - case GL_COMPRESSED_RGBA_FXT1_3DFX: - /* - * Round height and width to multiples of 4 and 8, - * divide the resulting product by 32 to get the number - * of blocks, and multiply by 32 = 128/8 to get the. - * number of bytes required. That is to say, just - * return the product. Remember that we are returning - * bytes, not texels, so we have shrunk the texture - * by a factor of the texel size. - */ - width = (width + 0x7) &~ 0x7; - height = (height + 0x3) &~ 0x3; - return width * height; - } - return 0; -} - - - /** * Allocate a new texture object. * Called via ctx->Driver.NewTextureObject. @@ -1500,9 +1839,12 @@ void tdfxInitTextureFuncs( struct dd_function_table *functions ) functions->TexEnv = tdfxTexEnv; functions->TexParameter = tdfxTexParameter; functions->ChooseTextureFormat = tdfxChooseTextureFormat; + functions->TexImage1D = tdfxTexImage1D; + functions->TexSubImage1D = tdfxTexSubImage1D; functions->TexImage2D = tdfxTexImage2D; functions->TexSubImage2D = tdfxTexSubImage2D; functions->IsTextureResident = tdfxIsTextureResident; + functions->CompressedTexImage2D = tdfxCompressedTexImage2D; + functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D; functions->UpdateTexturePalette = tdfxUpdateTexturePalette; } - diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texman.c b/src/mesa/drivers/dri/tdfx/tdfx_texman.c index 6f303aee666..2b2c93f1c32 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texman.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texman.c @@ -852,8 +852,8 @@ tdfxTMMoveInTM_NoLock( tdfxContextPtr fxMesa, struct gl_texture_object *tObj, if (ti->tm[TDFX_TMU0]) fxMesa->stats.memTexUpload += texmemsize; - texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, - &(ti->info)); + /*texmemsize = fxMesa->Glide.grTexTextureMemRequired(GR_MIPMAPLEVELMASK_BOTH, + &(ti->info));*/ ti->tm[TDFX_TMU1] = AllocTexMem(fxMesa, TDFX_TMU1, texmemsize); break; default: diff --git a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c index 3de73c45134..bb974279a2a 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_texstate.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_texstate.c @@ -26,6 +26,9 @@ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_texstate.c,v 1.2 2002/02/22 21:45:04 dawes Exp $ */ /* + * New fixes: + * Daniel Borca , 19 Jul 2004 + * * Original rewrite: * Gareth Hughes , 29 Sep - 1 Oct 2000 * @@ -899,11 +902,10 @@ SetupSingleTexEnvVoodoo3(GLcontext *ctx, int unit, } else if (baseFormat == GL_INTENSITY) { /* Av = Af * (1 - It) + Ac * It */ - /* XXX this is wrong */ - alphaComb.Function = GR_COMBINE_FUNCTION_LOCAL; - alphaComb.Factor = GR_COMBINE_FACTOR_NONE; + alphaComb.Function = GR_COMBINE_FUNCTION_BLEND; + alphaComb.Factor = GR_COMBINE_FACTOR_TEXTURE_ALPHA; alphaComb.Local = locala; - alphaComb.Other = GR_COMBINE_OTHER_NONE; + alphaComb.Other = GR_COMBINE_OTHER_CONSTANT; alphaComb.Invert = FXFALSE; } else { @@ -922,13 +924,18 @@ SetupSingleTexEnvVoodoo3(GLcontext *ctx, int unit, colorComb.Invert = FXFALSE; } else { - colorComb.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; - colorComb.Factor = GR_COMBINE_FACTOR_ONE; + colorComb.Function = GR_COMBINE_FUNCTION_BLEND; + colorComb.Factor = GR_COMBINE_FACTOR_TEXTURE_RGB; colorComb.Local = localc; - colorComb.Other = GR_COMBINE_OTHER_TEXTURE; + colorComb.Other = GR_COMBINE_OTHER_CONSTANT; colorComb.Invert = FXTRUE; } - /* XXX return GL_FALSE for modes we don't support */ + fxMesa->Color.MonoColor = PACK_RGBA32( + ctx->Texture.Unit[unit].EnvColor[0] * 255.0f, + ctx->Texture.Unit[unit].EnvColor[1] * 255.0f, + ctx->Texture.Unit[unit].EnvColor[2] * 255.0f, + ctx->Texture.Unit[unit].EnvColor[3] * 255.0f); + fxMesa->dirty |= TDFX_UPLOAD_CONSTANT_COLOR; break; case GL_REPLACE: @@ -1051,15 +1058,8 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, if (envMode0 == GL_MODULATE && envMode1 == GL_MODULATE) { GLboolean isalpha[TDFX_NUM_TMU]; - if (baseFormat0 == GL_ALPHA) - isalpha[tmu0] = GL_TRUE; - else - isalpha[tmu0] = GL_FALSE; - - if (baseFormat1 == GL_ALPHA) - isalpha[tmu1] = GL_TRUE; - else - isalpha[tmu1] = GL_FALSE; + isalpha[tmu0] = (baseFormat0 == GL_ALPHA); + isalpha[tmu1] = (baseFormat1 == GL_ALPHA); if (isalpha[TDFX_TMU1]) { fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; @@ -1105,7 +1105,7 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, fxMesa->AlphaCombine.Invert = FXFALSE; } else if (envMode0 == GL_REPLACE && envMode1 == GL_BLEND) { /* Quake */ - if (tmu1 == TDFX_TMU1) { + if (tmu0 == TDFX_TMU1) { fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; @@ -1198,14 +1198,9 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, else if (envMode0 == GL_MODULATE && envMode1 == GL_ADD) { /* Quake 3 sky */ GLboolean isalpha[TDFX_NUM_TMU]; - if (baseFormat0 == GL_ALPHA) - isalpha[tmu0] = GL_TRUE; - else - isalpha[tmu0] = GL_FALSE; - if (baseFormat1 == GL_ALPHA) - isalpha[tmu1] = GL_TRUE; - else - isalpha[tmu1] = GL_FALSE; + + isalpha[tmu0] = (baseFormat0 == GL_ALPHA); + isalpha[tmu1] = (baseFormat1 == GL_ALPHA); if (isalpha[TDFX_TMU1]) { fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; @@ -1250,8 +1245,102 @@ SetupDoubleTexEnvVoodoo3(GLcontext *ctx, int tmu0, fxMesa->AlphaCombine.Other = GR_COMBINE_OTHER_TEXTURE; fxMesa->AlphaCombine.Invert = FXFALSE; } + else if (envMode0 == GL_REPLACE && envMode1 == GL_ADD) { + /* Vulpine sky */ + GLboolean isalpha[TDFX_NUM_TMU]; + + isalpha[tmu0] = (baseFormat0 == GL_ALPHA); + isalpha[tmu1] = (baseFormat1 == GL_ALPHA); + + if (isalpha[TDFX_TMU1]) { + fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->TexCombine[1].FactorAlpha = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].InvertRGB = FXTRUE; + fxMesa->TexCombine[1].InvertAlpha = FXFALSE; + } else { + fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->TexCombine[1].FactorAlpha = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].InvertRGB = FXFALSE; + fxMesa->TexCombine[1].InvertAlpha = FXFALSE; + } + + if (isalpha[TDFX_TMU0]) { + fxMesa->TexCombine[0].FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER; + fxMesa->TexCombine[0].FactorRGB = GR_COMBINE_FACTOR_ONE; + fxMesa->TexCombine[0].FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_ONE; + fxMesa->TexCombine[0].InvertRGB = FXFALSE; + fxMesa->TexCombine[0].InvertAlpha = FXFALSE; + } else { + fxMesa->TexCombine[0].FunctionRGB = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + fxMesa->TexCombine[0].FactorRGB = GR_COMBINE_FACTOR_ONE; + fxMesa->TexCombine[0].FunctionAlpha = GR_COMBINE_FUNCTION_SCALE_OTHER_ADD_LOCAL; + fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_ONE; + fxMesa->TexCombine[0].InvertRGB = FXFALSE; + fxMesa->TexCombine[0].InvertAlpha = FXFALSE; + } + + fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_ONE; + fxMesa->ColorCombine.Local = localc; + fxMesa->ColorCombine.Other = GR_COMBINE_OTHER_TEXTURE; + fxMesa->ColorCombine.Invert = FXFALSE; + fxMesa->AlphaCombine.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + fxMesa->AlphaCombine.Factor = GR_COMBINE_FACTOR_ONE; + fxMesa->AlphaCombine.Local = locala; + fxMesa->AlphaCombine.Other = GR_COMBINE_OTHER_TEXTURE; + fxMesa->AlphaCombine.Invert = FXFALSE; + } + else if (envMode1 == GL_REPLACE) { + /* Homeworld2 */ + + fxMesa->TexCombine[1].FunctionRGB = GR_COMBINE_FUNCTION_ZERO; + fxMesa->TexCombine[1].FactorRGB = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].FunctionAlpha = GR_COMBINE_FUNCTION_ZERO; + fxMesa->TexCombine[1].FactorAlpha = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[1].InvertRGB = FXFALSE; + fxMesa->TexCombine[1].InvertAlpha = FXFALSE; + + fxMesa->TexCombine[0].FunctionRGB = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->TexCombine[0].FactorRGB = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[0].FunctionAlpha = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->TexCombine[0].FactorAlpha = GR_COMBINE_FACTOR_NONE; + fxMesa->TexCombine[0].InvertRGB = FXFALSE; + fxMesa->TexCombine[0].InvertAlpha = FXFALSE; + + if ((baseFormat0 == GL_RGB) && (baseFormat0 == GL_LUMINANCE)) { + fxMesa->AlphaCombine.Function = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->AlphaCombine.Factor = GR_COMBINE_FACTOR_NONE; + fxMesa->AlphaCombine.Local = locala; + fxMesa->AlphaCombine.Other = GR_COMBINE_OTHER_NONE; + fxMesa->AlphaCombine.Invert = FXFALSE; + } else { + fxMesa->AlphaCombine.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + fxMesa->AlphaCombine.Factor = GR_COMBINE_FACTOR_ONE; + fxMesa->AlphaCombine.Local = locala; + fxMesa->AlphaCombine.Other = GR_COMBINE_OTHER_TEXTURE; + fxMesa->AlphaCombine.Invert = FXFALSE; + } + if (baseFormat0 == GL_ALPHA) { + fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_LOCAL; + fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_NONE; + fxMesa->ColorCombine.Local = localc; + fxMesa->ColorCombine.Other = GR_COMBINE_OTHER_NONE; + fxMesa->ColorCombine.Invert = FXFALSE; + } else { + fxMesa->ColorCombine.Function = GR_COMBINE_FUNCTION_SCALE_OTHER; + fxMesa->ColorCombine.Factor = GR_COMBINE_FACTOR_ONE; + fxMesa->ColorCombine.Local = localc; + fxMesa->ColorCombine.Other = GR_COMBINE_OTHER_TEXTURE; + fxMesa->ColorCombine.Invert = FXFALSE; + } + } else { - /*_mesa_problem(ctx, "%s: Unexpected dual texture mode encountered", __FUNCTION__);*/ + _mesa_problem(ctx, "%s: Unexpected dual texture mode encountered", __FUNCTION__); return GL_FALSE; } @@ -1329,7 +1418,7 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) GLint u; if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti->paltype; fxMesa->TexPalette.Data = &(ti->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -1367,7 +1456,7 @@ setupSingleTMU(tdfxContextPtr fxMesa, struct gl_texture_object *tObj) } if (ti->info.format == GR_TEXFMT_P_8 && !ctx->Texture.SharedPalette) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti->paltype; fxMesa->TexPalette.Data = &(ti->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -1482,8 +1571,8 @@ selectSingleTMUSrc(tdfxContextPtr fxMesa, GLint tmu, FxBool LODblend) static void print_state(tdfxContextPtr fxMesa) { GLcontext *ctx = fxMesa->glCtx; - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0]._Current; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1]._Current; GLenum base0 = tObj0->Image[0][tObj0->BaseLevel] ? tObj0->Image[0][tObj0->BaseLevel]->Format : 99; GLenum base1 = tObj1->Image[0][tObj1->BaseLevel] ? tObj1->Image[0][tObj1->BaseLevel]->Format : 99; @@ -1517,7 +1606,7 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) int tmu; GLenum envMode, baseFormat; - tObj = ctx->Texture.Unit[unit].Current2D; + tObj = ctx->Texture.Unit[unit]._Current; if (tObj->Image[0][tObj->BaseLevel]->Border > 0) { FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_BORDER, GL_TRUE); return; @@ -1544,10 +1633,10 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) if (TDFX_IS_NAPALM(fxMesa)) { /* see if we really need to update the unit */ - if (fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled || + if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled || envMode != fxMesa->TexState.EnvMode[0] || envMode == GL_COMBINE_EXT || - baseFormat != fxMesa->TexState.TexFormat[0]) { + baseFormat != fxMesa->TexState.TexFormat[0]*/) { struct tdfx_texcombine_ext *otherEnv; if (!SetupTexEnvNapalm(ctx, GL_TRUE, &ctx->Texture.Unit[unit], baseFormat, @@ -1578,30 +1667,34 @@ static void setupTextureSingleTMU(GLcontext * ctx, GLuint unit) otherEnv->Alpha.Shift = 0; otherEnv->Alpha.Invert = FXFALSE; +#if 0/*JJJ*/ fxMesa->TexState.Enabled[unit] = ctx->Texture.Unit[unit]._ReallyEnabled; fxMesa->TexState.EnvMode[0] = envMode; fxMesa->TexState.TexFormat[0] = baseFormat; fxMesa->TexState.EnvMode[1] = 0; fxMesa->TexState.TexFormat[1] = 0; +#endif } } else { /* Voodoo3 */ /* see if we really need to update the unit */ - if (fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled || + if (1/*fxMesa->TexState.Enabled[unit] != ctx->Texture.Unit[unit]._ReallyEnabled || envMode != fxMesa->TexState.EnvMode[0] || envMode == GL_COMBINE_EXT || - baseFormat != fxMesa->TexState.TexFormat[0]) { - if (!SetupSingleTexEnvVoodoo3(ctx, tmu, envMode, baseFormat)) { + baseFormat != fxMesa->TexState.TexFormat[0]*/) { + if (!SetupSingleTexEnvVoodoo3(ctx, unit, envMode, baseFormat)) { /* software fallback */ FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } +#if 0/*JJJ*/ fxMesa->TexState.Enabled[unit] = ctx->Texture.Unit[unit]._ReallyEnabled; fxMesa->TexState.EnvMode[0] = envMode; fxMesa->TexState.TexFormat[0] = baseFormat; fxMesa->TexState.EnvMode[1] = 0; fxMesa->TexState.TexFormat[1] = 0; +#endif } } } @@ -1731,12 +1824,12 @@ setupDoubleTMU(tdfxContextPtr fxMesa, if (!ctx->Texture.SharedPalette) { if (ti0->info.format == GR_TEXFMT_P_8) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti0->paltype; fxMesa->TexPalette.Data = &(ti0->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } else if (ti1->info.format == GR_TEXFMT_P_8) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti1->paltype; fxMesa->TexPalette.Data = &(ti1->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -1823,8 +1916,8 @@ setupDoubleTMU(tdfxContextPtr fxMesa, static void setupTextureDoubleTMU(GLcontext * ctx) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[1]._Current; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[0]._Current; tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); struct gl_texture_image *baseImage0 = tObj0->Image[0][tObj0->BaseLevel]; @@ -1851,29 +1944,33 @@ static void setupTextureDoubleTMU(GLcontext * ctx) GLboolean hw1 = GL_TRUE, hw2 = GL_TRUE; /* check if we really need to update glide unit 1 */ - if (fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled || + if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled || envMode0 != fxMesa->TexState.EnvMode[1] || envMode0 == GL_COMBINE_EXT || baseImage0->Format != fxMesa->TexState.TexFormat[1] || - (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)) { + (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) { hw1 = SetupTexEnvNapalm(ctx, GL_TRUE, &ctx->Texture.Unit[0], baseImage0->Format, &fxMesa->TexCombineExt[1]); +#if 0/*JJJ*/ fxMesa->TexState.EnvMode[1] = envMode0; fxMesa->TexState.TexFormat[1] = baseImage0->Format; fxMesa->TexState.Enabled[0] = ctx->Texture.Unit[0]._ReallyEnabled; +#endif } /* check if we really need to update glide unit 0 */ - if (fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled || + if (1/*fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled || envMode1 != fxMesa->TexState.EnvMode[0] || envMode1 == GL_COMBINE_EXT || baseImage1->Format != fxMesa->TexState.TexFormat[0] || - (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)) { + (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) { hw2 = SetupTexEnvNapalm(ctx, GL_FALSE, &ctx->Texture.Unit[1], baseImage1->Format, &fxMesa->TexCombineExt[0]); +#if 0/*JJJ*/ fxMesa->TexState.EnvMode[0] = envMode1; fxMesa->TexState.TexFormat[0] = baseImage1->Format; fxMesa->TexState.Enabled[1] = ctx->Texture.Unit[1]._ReallyEnabled; +#endif } @@ -1889,7 +1986,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) unit0 = 0; unit1 = 1 - unit0; - if (fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled || + if (1/*fxMesa->TexState.Enabled[0] != ctx->Texture.Unit[0]._ReallyEnabled || fxMesa->TexState.Enabled[1] != ctx->Texture.Unit[1]._ReallyEnabled || envMode0 != fxMesa->TexState.EnvMode[unit0] || envMode0 == GL_COMBINE_EXT || @@ -1897,7 +1994,7 @@ static void setupTextureDoubleTMU(GLcontext * ctx) envMode1 == GL_COMBINE_EXT || baseImage0->Format != fxMesa->TexState.TexFormat[unit0] || baseImage1->Format != fxMesa->TexState.TexFormat[unit1] || - (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)) { + (fxMesa->Fallback & TDFX_FALLBACK_TEXTURE_ENV)*/) { if (!SetupDoubleTexEnvVoodoo3(ctx, unit0, ctx->Texture.Unit[0].EnvMode, baseImage0->Format, @@ -1905,12 +2002,14 @@ static void setupTextureDoubleTMU(GLcontext * ctx) FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_TRUE); } +#if 0/*JJJ*/ fxMesa->TexState.EnvMode[unit0] = envMode0; fxMesa->TexState.TexFormat[unit0] = baseImage0->Format; fxMesa->TexState.EnvMode[unit1] = envMode1; fxMesa->TexState.TexFormat[unit1] = baseImage1->Format; fxMesa->TexState.Enabled[0] = ctx->Texture.Unit[0]._ReallyEnabled; fxMesa->TexState.Enabled[1] = ctx->Texture.Unit[1]._ReallyEnabled; +#endif } } } @@ -1924,20 +2023,20 @@ tdfxUpdateTextureState( GLcontext *ctx ) FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_BORDER, GL_FALSE); FALLBACK(fxMesa, TDFX_FALLBACK_TEXTURE_ENV, GL_FALSE); - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && + if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT) && ctx->Texture.Unit[1]._ReallyEnabled == 0) { LOCK_HARDWARE( fxMesa ); /* XXX remove locking eventually */ setupTextureSingleTMU(ctx, 0); UNLOCK_HARDWARE( fxMesa ); } else if (ctx->Texture.Unit[0]._ReallyEnabled == 0 && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { + ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { LOCK_HARDWARE( fxMesa ); setupTextureSingleTMU(ctx, 1); UNLOCK_HARDWARE( fxMesa ); } - else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[1]._ReallyEnabled == TEXTURE_2D_BIT) { + else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT) && + ctx->Texture.Unit[1]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { LOCK_HARDWARE( fxMesa ); setupTextureDoubleTMU(ctx); UNLOCK_HARDWARE( fxMesa ); @@ -2009,8 +2108,8 @@ void tdfxUpdateTextureBinding( GLcontext *ctx ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct gl_texture_object *tObj0 = ctx->Texture.Unit[0].Current2D; - struct gl_texture_object *tObj1 = ctx->Texture.Unit[1].Current2D; + struct gl_texture_object *tObj0 = ctx->Texture.Unit[0]._Current; + struct gl_texture_object *tObj1 = ctx->Texture.Unit[1]._Current; tdfxTexInfo *ti0 = TDFX_TEXTURE_DATA(tObj0); tdfxTexInfo *ti1 = TDFX_TEXTURE_DATA(tObj1); @@ -2021,12 +2120,12 @@ tdfxUpdateTextureBinding( GLcontext *ctx ) fxMesa->sScale0 = ti0->sScale; fxMesa->tScale0 = ti0->tScale; if (ti0->info.format == GR_TEXFMT_P_8) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti0->paltype; fxMesa->TexPalette.Data = &(ti0->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } else if (ti1 && ti1->info.format == GR_TEXFMT_P_8) { - fxMesa->TexPalette.Type = GR_TEXTABLE_PALETTE_6666_EXT; + fxMesa->TexPalette.Type = ti1->paltype; fxMesa->TexPalette.Data = &(ti1->palette); fxMesa->dirty |= TDFX_UPLOAD_TEXTURE_PALETTE; } @@ -2036,7 +2135,7 @@ tdfxUpdateTextureBinding( GLcontext *ctx ) fxMesa->tScale1 = ti1->tScale; } - if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && + if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT) && ctx->Texture.Unit[0]._ReallyEnabled == 0) { /* Only unit 0 2D enabled */ if (shared->umaTexMemory) { @@ -2070,7 +2169,7 @@ tdfxUpdateTextureBinding( GLcontext *ctx ) } } else if (ctx->Texture.Unit[0]._ReallyEnabled == 0 && - ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) { + ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { /* Only unit 1 2D enabled */ if (shared->umaTexMemory) { fxMesa->TexSource[0].StartAddress = ti1->tm[0]->startAddr; @@ -2078,8 +2177,8 @@ tdfxUpdateTextureBinding( GLcontext *ctx ) fxMesa->TexSource[0].Info = &(ti1->info); } } - else if (ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT && - ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT) { + else if (ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT) && + ctx->Texture.Unit[0]._ReallyEnabled & (TEXTURE_1D_BIT|TEXTURE_2D_BIT)) { /* Both 2D enabled */ if (shared->umaTexMemory) { const FxU32 tmu0 = 0, tmu1 = 1; diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c index c3398c73fc6..1f0e03c04bd 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c @@ -25,7 +25,10 @@ */ /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_tris.c,v 1.4 2002/10/30 12:52:01 alanh Exp $ */ -/* Authors: +/* New fixes: + * Daniel Borca , 19 Jul 2004 + * + * Authors: * Keith Whitwell */ @@ -68,8 +71,14 @@ do { \ fxMesa->draw_triangle( fxMesa, a, b, d ); \ fxMesa->draw_triangle( fxMesa, b, c, d ); \ } else { \ - fxMesa->Glide.grDrawTriangle( a, b, d ); \ - fxMesa->Glide.grDrawTriangle( b, c, d ); \ + tdfxVertex *_v_[4]; \ + _v_[0] = d; \ + _v_[1] = a; \ + _v_[2] = b; \ + _v_[3] = c; \ + fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ + /*fxMesa->Glide.grDrawTriangle( a, b, d );*/\ + /*fxMesa->Glide.grDrawTriangle( b, c, d );*/\ } \ } while (0) @@ -78,15 +87,15 @@ do { \ if (DO_FALLBACK) \ fxMesa->draw_line( fxMesa, v0, v1 ); \ else { \ - v0->v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ - v0->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ - v1->v.x += LINE_X_OFFSET - TRI_X_OFFSET; \ - v1->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v0->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x += LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y += LINE_Y_OFFSET - TRI_Y_OFFSET; \ fxMesa->Glide.grDrawLine( v0, v1 ); \ - v0->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ - v0->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ - v1->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; \ - v1->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v0->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ + v1->x -= LINE_X_OFFSET - TRI_X_OFFSET; \ + v1->y -= LINE_Y_OFFSET - TRI_Y_OFFSET; \ } \ } while (0) @@ -95,11 +104,11 @@ do { \ if (DO_FALLBACK) \ fxMesa->draw_point( fxMesa, v0 ); \ else { \ - v0->v.x += PNT_X_OFFSET - TRI_X_OFFSET; \ - v0->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ + v0->x += PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y += PNT_Y_OFFSET - TRI_Y_OFFSET; \ fxMesa->Glide.grDrawPoint( v0 ); \ - v0->v.x -= PNT_X_OFFSET - TRI_X_OFFSET; \ - v0->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ + v0->x -= PNT_X_OFFSET - TRI_X_OFFSET; \ + v0->y -= PNT_Y_OFFSET - TRI_Y_OFFSET; \ } \ } while (0) @@ -120,49 +129,45 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) { - dst->win[0] = src->tv.x - fxMesa->x_offset; - dst->win[1] = src->tv.y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); - dst->win[2] = src->tv.z; + dst->win[0] = src->x - fxMesa->x_offset; + dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); + dst->win[2] = src->z; dst->win[3] = 1.0; - dst->color[0] = src->tv.color.red; - dst->color[1] = src->tv.color.green; - dst->color[2] = src->tv.color.blue; - dst->color[3] = src->tv.color.alpha; + dst->color[0] = src->color[2]; + dst->color[1] = src->color[1]; + dst->color[2] = src->color[0]; + dst->color[3] = src->color[3]; } else { - GLfloat w = 1.0 / src->v.rhw; - - dst->win[0] = src->v.x - fxMesa->x_offset; - dst->win[1] = fxMesa->screen_height - fxMesa->y_offset - src->v.y; - dst->win[2] = src->v.z; - dst->win[3] = src->v.rhw; - - dst->color[0] = src->v.color.red; - dst->color[1] = src->v.color.green; - dst->color[2] = src->v.color.blue; - dst->color[3] = src->v.color.alpha; - - if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJECT) { - dst->texcoord[0][0] = fxMesa->sScale0 * w * src->pv.tu0; - dst->texcoord[0][1] = fxMesa->tScale0 * w * src->pv.tv0; - dst->texcoord[0][3] = w * src->pv.tq0; - - if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { - dst->texcoord[1][0] = fxMesa->sScale1 * w * src->pv.tu1; - dst->texcoord[1][1] = fxMesa->tScale1 * w * src->pv.tv1; - dst->texcoord[1][3] = w * src->pv.tq1; - } - } else if (fxMesa->SetupIndex & TDFX_TEX0_BIT) { - dst->texcoord[0][0] = fxMesa->sScale0 * w * src->v.tu0; - dst->texcoord[0][1] = fxMesa->tScale0 * w * src->v.tv0; + GLfloat w = 1.0 / src->rhw; + + dst->win[0] = src->x - fxMesa->x_offset; + dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); + dst->win[2] = src->z; + dst->win[3] = src->rhw; + + dst->color[0] = src->color[2]; + dst->color[1] = src->color[1]; + dst->color[2] = src->color[0]; + dst->color[3] = src->color[3]; + + dst->texcoord[0][0] = 1.0 / fxMesa->sScale0 * w * src->tu0; + dst->texcoord[0][1] = 1.0 / fxMesa->tScale0 * w * src->tv0; + if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ1 || fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { + dst->texcoord[0][3] = w * src->tq0; + } else { dst->texcoord[0][3] = 1.0; + } - if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { - dst->texcoord[1][0] = fxMesa->sScale1 * w * src->v.tu1; - dst->texcoord[1][1] = fxMesa->tScale1 * w * src->v.tv1; + if (fxMesa->SetupIndex & TDFX_TEX1_BIT) { + dst->texcoord[1][0] = 1.0 / fxMesa->sScale1 * w * src->tu1; + dst->texcoord[1][1] = 1.0 / fxMesa->tScale1 * w * src->tv1; + if (fxMesa->vertexFormat == TDFX_LAYOUT_PROJ2) { + dst->texcoord[1][3] = w * src->tq1; + } else { dst->texcoord[1][3] = 1.0; - } + } } } @@ -214,27 +219,22 @@ tdfx_fallback_point( tdfxContextPtr fxMesa, static void tdfx_print_vertex( GLcontext *ctx, const tdfxVertex *v ) { - tdfxContextPtr imesa = TDFX_CONTEXT( ctx ); + tdfxContextPtr tmesa = TDFX_CONTEXT( ctx ); fprintf(stderr, "vertex at %p\n", (void *)v); - if (imesa->vertexFormat == TDFX_LAYOUT_TINY) { - fprintf(stderr, "x %f y %f z %f\n", v->v.x, v->v.y, v->v.z); - fprintf(stderr, "r %d g %d b %d a %d\n", - v->tv.color.red, - v->tv.color.green, - v->tv.color.blue, - v->tv.color.alpha); + if (tmesa->vertexFormat == TDFX_LAYOUT_TINY) { + fprintf(stderr, "x %f y %f z %f\n", v->x, v->y, v->z); } else { fprintf(stderr, "x %f y %f z %f oow %f\n", - v->v.x, v->v.y, v->v.z, v->v.rhw); - fprintf(stderr, "r %d g %d b %d a %d\n", - v->v.color.red, - v->v.color.green, - v->v.color.blue, - v->v.color.alpha); + v->x, v->y, v->z, v->rhw); } + fprintf(stderr, "r %d g %d b %d a %d\n", + v->color[0], + v->color[1], + v->color[2], + v->color[3]); fprintf(stderr, "\n"); } @@ -327,34 +327,36 @@ static struct { #define VERTEX tdfxVertex #define TAB rast_tab -#define TDFX_COLOR( dst, src ) \ -do { \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[0], (src)[2]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[1], (src)[1]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[2], (src)[0]); \ - UNCLAMPED_FLOAT_TO_UBYTE((dst)[3], (src)[3]); \ -} while (0) - #define DEPTH_SCALE 1.0 #define UNFILLED_TRI unfilled_tri #define UNFILLED_QUAD unfilled_quad -#define VERT_X(_v) _v->v.x -#define VERT_Y(_v) _v->v.y -#define VERT_Z(_v) _v->v.z +#define VERT_X(_v) _v->x +#define VERT_Y(_v) _v->y +#define VERT_Z(_v) _v->z #define AREA_IS_CCW( a ) (a < 0) -#define GET_VERTEX(e) (fxMesa->verts + (e<vertex_stride_shift)) +#define GET_VERTEX(e) (fxMesa->verts + (e)) + +#define VERT_SET_RGBA( dst, f ) \ +do { \ + UNCLAMPED_FLOAT_TO_UBYTE(dst->color[2], f[0]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->color[1], f[1]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->color[0], f[2]);\ + UNCLAMPED_FLOAT_TO_UBYTE(dst->color[3], f[3]);\ +} while (0) -#define VERT_SET_RGBA( v, c ) TDFX_COLOR( v->ub4[coloroffset], c ) -#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] -#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] -#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] +#define VERT_COPY_RGBA( v0, v1 ) \ + *(GLuint *)&v0->color = *(GLuint *)&v1->color + +#define VERT_SAVE_RGBA( idx ) \ + *(GLuint *)&color[idx] = *(GLuint *)&v[idx]->color + +#define VERT_RESTORE_RGBA( idx ) \ + *(GLuint *)&v[idx]->color = *(GLuint *)&color[idx] #define LOCAL_VARS(n) \ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ - GLuint coloroffset = (fxMesa->vertexFormat == \ - TDFX_LAYOUT_TINY) ? 3 : 4; \ - GLuint color[n]; \ - (void) color; (void)coloroffset + GLubyte color[n][4]; \ + (void) color; @@ -554,6 +556,7 @@ static void init_rast_tab( void ) /* Accelerate vertex buffer rendering when renderindex == 0 and * there is no clipping. */ +#define INIT(x) tdfxRenderPrimitive( ctx, x ) static void tdfx_render_vb_points( GLcontext *ctx, GLuint start, @@ -561,25 +564,24 @@ static void tdfx_render_vb_points( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); - int stride = 1<verts; GLint i; (void) flags; + INIT(GL_POINTS); + /* Adjust point coords */ - for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x += PNT_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y += PNT_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x += PNT_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += PNT_Y_OFFSET - TRI_Y_OFFSET; } fxMesa->Glide.grDrawVertexArrayContiguous( GR_POINTS, count-start, - fxVB, stride); + fxVB + start, sizeof(tdfxVertex)); /* restore point coords */ - for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x -= PNT_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y -= PNT_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x -= PNT_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= PNT_Y_OFFSET - TRI_Y_OFFSET; } } @@ -589,26 +591,25 @@ static void tdfx_render_vb_line_strip( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); - int stride = 1<verts; GLint i; (void) flags; + INIT(GL_LINE_STRIP); + /* adjust line coords */ - for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; } fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-start, - fxVB, 1<v.x -= LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; } } @@ -618,36 +619,34 @@ static void tdfx_render_vb_line_loop( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); - int stride = 1<verts; GLint i; GLint j = start; (void) flags; + INIT(GL_LINE_LOOP); + if (!(flags & PRIM_BEGIN)) { - fxVB += (1 << shift); j++; } /* adjust line coords */ - for (i = start, tmp = tmp2; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; } fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINE_STRIP, count-j, - fxVB, 1<Glide.grDrawLine( fxMesa->verts + ((count - 1)<verts + (start<Glide.grDrawLine( fxVB + (count - 1), + fxVB + start ); /* restore line coords */ - for (i = start, tmp = tmp2; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x -= LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; } } @@ -657,26 +656,25 @@ static void tdfx_render_vb_lines( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); - int stride = 1<verts; GLint i; (void) flags; + INIT(GL_LINES); + /* adjust line coords */ - for (i = start, tmp = fxVB; i < count; i++, tmp += stride) { - ((tdfxVertexPtr)tmp)->v.x += LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y += LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x += LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y += LINE_Y_OFFSET - TRI_Y_OFFSET; } fxMesa->Glide.grDrawVertexArrayContiguous( GR_LINES, count-start, - fxVB, 1<v.x -= LINE_X_OFFSET - TRI_X_OFFSET; - ((tdfxVertexPtr)tmp)->v.y -= LINE_Y_OFFSET - TRI_Y_OFFSET; + for (i = start; i < count; i++) { + fxVB[i].x -= LINE_X_OFFSET - TRI_X_OFFSET; + fxVB[i].y -= LINE_Y_OFFSET - TRI_Y_OFFSET; } } @@ -686,12 +684,28 @@ static void tdfx_render_vb_triangles( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); + tdfxVertex *fxVB = fxMesa->verts; (void) flags; + INIT(GL_TRIANGLES); + +#if 0 + /* [dBorca] + * apparently, this causes troubles with some programs (GLExcess); + * might be a bug in Glide... However, "grDrawVertexArrayContiguous" + * eventually calls "grDrawTriangle" for GR_TRIANGLES, so we're better + * off doing it by hand... + */ fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLES, count-start, - fxVB, 1<Glide.grDrawTriangle(fxVB + (j-2), fxVB + (j-1), fxVB + j); + } + } +#endif } @@ -701,18 +715,19 @@ static void tdfx_render_vb_tri_strip( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); + tdfxVertex *fxVB = fxMesa->verts; int mode; (void) flags; + INIT(GL_TRIANGLE_STRIP); + /* fprintf(stderr, "%s/%d\n", __FUNCTION__, 1<Glide.grDrawVertexArrayContiguous( mode, count-start, - fxVB, 1<vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); + tdfxVertex *fxVB = fxMesa->verts; (void) flags; + INIT(GL_TRIANGLE_FAN); + fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_FAN, count-start, - fxVB, 1<vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts; + tdfxVertex *fxVB = fxMesa->verts; GLuint i; (void) flags; + + INIT(GL_QUADS); - for (i = start ; i < count-3 ; i += 4 ) { -#define VERT(x) (fxVB + ((x)<Glide.grDrawTriangle( VERT(i), VERT(i+1), VERT(i+3) ); - fxMesa->Glide.grDrawTriangle( VERT(i+1), VERT(i+2), VERT(i+3) ); + for (i = start + 3 ; i < count ; i += 4 ) { +#define VERT(x) (fxVB + (x)) + tdfxVertex *_v_[4]; + _v_[0] = VERT(i); + _v_[1] = VERT(i-3); + _v_[2] = VERT(i-2); + _v_[3] = VERT(i-1); + fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_); + /*fxMesa->Glide.grDrawTriangle( VERT(i-3), VERT(i-2), VERT(i) );*/ + /*fxMesa->Glide.grDrawTriangle( VERT(i-2), VERT(i-1), VERT(i) );*/ #undef VERT } } @@ -755,14 +778,15 @@ static void tdfx_render_vb_quad_strip( GLcontext *ctx, GLuint flags ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - GLuint shift = fxMesa->vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); + tdfxVertex *fxVB = fxMesa->verts; (void) flags; + INIT(GL_QUAD_STRIP); + count -= (count-start)&1; fxMesa->Glide.grDrawVertexArrayContiguous( GR_TRIANGLE_STRIP, - count-start, fxVB, 1<vertex_stride_shift; - GLubyte *fxVB = fxMesa->verts + (start << shift); + tdfxVertex *fxVB = fxMesa->verts; (void) flags; + + INIT(GL_POLYGON); fxMesa->Glide.grDrawVertexArrayContiguous( GR_POLYGON, count-start, - fxVB, 1<Glide.grDrawTriangle( VERT(v0), VERT(v1), VERT(v2) ) #define RENDER_QUAD( v0, v1, v2, v3 ) \ - tdfx_draw_quad( fxMesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) + do { \ + tdfxVertex *_v_[4]; \ + _v_[0] = VERT(v3); \ + _v_[1] = VERT(v0); \ + _v_[2] = VERT(v1); \ + _v_[3] = VERT(v2); \ + fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, 4, _v_);\ + /*fxMesa->Glide.grDrawTriangle( VERT(v0), VERT(v1), VERT(v3) );*/\ + /*fxMesa->Glide.grDrawTriangle( VERT(v1), VERT(v2), VERT(v3) );*/\ + } while (0) #define INIT(x) tdfxRenderPrimitive( ctx, x ) #undef LOCAL_VARS #define LOCAL_VARS \ tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \ - GLubyte *vertptr = (GLubyte *)fxMesa->verts; \ - const GLuint vertshift = fxMesa->vertex_stride_shift; \ + tdfxVertex *vertptr = fxMesa->verts; \ const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ (void) elt; @@ -848,6 +882,14 @@ static void (*tdfx_render_tab_verts[GL_POLYGON+2])(GLcontext *, #define ELT(x) elt[x] #include "tnl_dd/t_dd_rendertmp.h" +/* Verts, no clipping. + */ +#undef ELT +#undef TAG +#define TAG(x) tdfx_##x##_verts +#define ELT(x) x +/*#include "tnl_dd/t_dd_rendertmp.h"*/ + /**********************************************************************/ @@ -888,14 +930,22 @@ static void tdfxRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) static void tdfxFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, GLuint n ) { - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - GLubyte *vertptr = (GLubyte *)fxMesa->verts; - const GLuint vertshift = fxMesa->vertex_stride_shift; - const GLuint *start = (const GLuint *)VERT(elts[0]); int i; - - for (i = 2 ; i < n ; i++) { - fxMesa->Glide.grDrawTriangle( VERT(elts[i-1]), VERT(elts[i]), start ); + tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); + tdfxVertex *vertptr = fxMesa->verts; + if (n == 3) { + fxMesa->Glide.grDrawTriangle( VERT(elts[0]), VERT(elts[1]), VERT(elts[2]) ); + } else if (n <= 32) { + tdfxVertex *newvptr[32]; + for (i = 0 ; i < n ; i++) { + newvptr[i] = VERT(elts[i]); + } + fxMesa->Glide.grDrawVertexArray(GR_TRIANGLE_FAN, n, newvptr); + } else { + const tdfxVertex *start = VERT(elts[0]); + for (i = 2 ; i < n ; i++) { + fxMesa->Glide.grDrawTriangle( start, VERT(elts[i-1]), VERT(elts[i]) ); + } } } @@ -1166,7 +1216,7 @@ static void tdfxRenderFinish( GLcontext *ctx ) /**********************************************************************/ static char *fallbackStrings[] = { - "1D/3D Texture map", + "3D/Rect/Cube Texture map", "glDrawBuffer(GL_FRONT_AND_BACK)", "Separate specular color", "glEnable/Disable(GL_STENCIL_TEST)", diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vb.c b/src/mesa/drivers/dri/tdfx/tdfx_vb.c index b7d75bb4e46..aff90cab73b 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_vb.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_vb.c @@ -39,35 +39,19 @@ #include "tdfx_state.h" #include "tdfx_render.h" -static void copy_pv_rgba4( GLcontext *ctx, GLuint edst, GLuint esrc ) +static void copy_pv( GLcontext *ctx, GLuint edst, GLuint esrc ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; - GLuint shift = fxMesa->vertex_stride_shift; - tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); - tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); - dst->ui[4] = src->ui[4]; + tdfxVertex *dst = fxMesa->verts + edst; + tdfxVertex *src = fxMesa->verts + esrc; + *(GLuint *)&dst->color = *(GLuint *)&src->color; } -static void copy_pv_rgba3( GLcontext *ctx, GLuint edst, GLuint esrc ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; - GLuint shift = fxMesa->vertex_stride_shift; - tdfxVertex *dst = (tdfxVertex *)(tdfxverts + (edst << shift)); - tdfxVertex *src = (tdfxVertex *)(tdfxverts + (esrc << shift)); - dst->ui[3] = src->ui[3]; -} - -typedef void (*tdfx_emit_func)( GLcontext *, GLuint, GLuint, void *, GLuint ); - static struct { - tdfx_emit_func emit; + tnl_emit_func emit; tnl_interp_func interp; tnl_copy_pv_func copy_pv; GLboolean (*check_tex_sizes)( GLcontext *ctx ); - GLuint vertex_size; - GLuint vertex_stride_shift; GLuint vertex_format; } setup_tab[TDFX_MAX_SETUP]; @@ -87,7 +71,7 @@ static void interp_extras( GLcontext *ctx, /*fprintf(stderr, "%s\n", __FUNCTION__);*/ if (VB->ColorPtr[1]) { - INTERP_4CHAN( t, + INTERP_4F( t, GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], out), GET_COLOR(VB->ColorPtr[1], in) ); @@ -106,7 +90,7 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; if (VB->ColorPtr[1]) { - COPY_CHAN4( GET_COLOR(VB->ColorPtr[1], dst), + COPY_4FV( GET_COLOR(VB->ColorPtr[1], dst), GET_COLOR(VB->ColorPtr[1], src) ); } @@ -163,6 +147,29 @@ static void copy_pv_extras( GLcontext *ctx, GLuint dst, GLuint src ) #include "tdfx_vbtmp.h" +/* fogc { */ +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_FOGC_BIT) +#define TAG(x) x##_wgf +#include "tdfx_vbtmp.h" + +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_FOGC_BIT) +#define TAG(x) x##_wgt0f +#include "tdfx_vbtmp.h" + +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|TDFX_FOGC_BIT) +#define TAG(x) x##_wgt0t1f +#include "tdfx_vbtmp.h" + +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_PTEX_BIT|TDFX_FOGC_BIT) +#define TAG(x) x##_wgpt0f +#include "tdfx_vbtmp.h" + +#define IND (TDFX_XYZ_BIT|TDFX_RGBA_BIT|TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT|\ + TDFX_PTEX_BIT|TDFX_FOGC_BIT) +#define TAG(x) x##_wgpt0t1f +#include "tdfx_vbtmp.h" +/* fogc } */ + static void init_setup_tab( void ) { @@ -178,19 +185,27 @@ static void init_setup_tab( void ) init_t0t1(); init_gt0(); init_gt0t1(); + + /* fogcoord */ + init_wgf(); + init_wgt0f(); + init_wgt0t1f(); + init_wgpt0f(); + init_wgpt0t1f(); } void tdfxPrintSetupFlags(char *msg, GLuint flags ) { - fprintf(stderr, "%s(%x): %s%s%s%s%s\n", + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", msg, (int)flags, (flags & TDFX_XYZ_BIT) ? " xyz," : "", (flags & TDFX_W_BIT) ? " w," : "", (flags & TDFX_RGBA_BIT) ? " rgba," : "", (flags & TDFX_TEX0_BIT) ? " tex-0," : "", - (flags & TDFX_TEX1_BIT) ? " tex-1," : ""); + (flags & TDFX_TEX1_BIT) ? " tex-1," : "", + (flags & TDFX_FOGC_BIT) ? " fogc," : ""); } @@ -210,7 +225,6 @@ void tdfxCheckTexSizes( GLcontext *ctx ) FLUSH_BATCH(fxMesa); fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; fxMesa->vertexFormat = setup_tab[ind].vertex_format; - fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; /* This is required as we have just changed the vertex * format, so the interp and copy routines must also change. @@ -230,8 +244,7 @@ void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, GLuint newinputs ) { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); - GLubyte *v = (fxMesa->verts + (start<vertex_stride_shift)); - GLuint stride = 1<vertex_stride_shift; + tdfxVertex *v = fxMesa->verts + start; newinputs |= fxMesa->SetupNewInputs; fxMesa->SetupNewInputs = 0; @@ -240,12 +253,15 @@ void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, return; if (newinputs & VERT_BIT_POS) { - setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v, stride ); + setup_tab[fxMesa->SetupIndex].emit( ctx, start, count, v ); } else { GLuint ind = 0; if (newinputs & VERT_BIT_COLOR0) ind |= TDFX_RGBA_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= TDFX_FOGC_BIT; if (newinputs & VERT_BIT_TEX0) ind |= TDFX_TEX0_BIT; @@ -259,7 +275,7 @@ void tdfxBuildVertices( GLcontext *ctx, GLuint start, GLuint count, ind &= fxMesa->SetupIndex; if (ind) { - setup_tab[ind].emit( ctx, start, count, v, stride ); + setup_tab[ind].emit( ctx, start, count, v ); } } } @@ -271,15 +287,25 @@ void tdfxChooseVertexState( GLcontext *ctx ) tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); GLuint ind = TDFX_XYZ_BIT|TDFX_RGBA_BIT; - if (ctx->Texture._EnabledUnits & 0x2) - /* unit 1 enabled */ - ind |= TDFX_W_BIT|TDFX_TEX1_BIT|TDFX_TEX0_BIT; - else if (ctx->Texture._EnabledUnits & 0x1) + fxMesa->tmu_source[0] = 0; + fxMesa->tmu_source[1] = 1; + + if (ctx->Texture._EnabledUnits & 0x2) { + if (ctx->Texture._EnabledUnits & 0x1) { + ind |= TDFX_TEX1_BIT; + } + ind |= TDFX_W_BIT|TDFX_TEX0_BIT; + fxMesa->tmu_source[0] = 1; + fxMesa->tmu_source[1] = 0; + } else if (ctx->Texture._EnabledUnits & 0x1) { /* unit 0 enabled */ ind |= TDFX_W_BIT|TDFX_TEX0_BIT; - else if (ctx->Fog.Enabled) - ind |= TDFX_W_BIT; - + } + + if (fxMesa->Fog.Mode == GR_FOG_WITH_TABLE_ON_FOGCOORD_EXT) { + ind |= TDFX_FOGC_BIT; + } + fxMesa->SetupIndex = ind; if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { @@ -294,7 +320,6 @@ void tdfxChooseVertexState( GLcontext *ctx ) FLUSH_BATCH(fxMesa); fxMesa->dirty |= TDFX_UPLOAD_VERTEX_LAYOUT; fxMesa->vertexFormat = setup_tab[ind].vertex_format; - fxMesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; } } @@ -310,10 +335,8 @@ void tdfxInitVB( GLcontext *ctx ) firsttime = 0; } - fxMesa->verts = (GLubyte *)ALIGN_MALLOC(size * sizeof(tdfxVertex), 32); - fxMesa->vertexFormat = setup_tab[TDFX_XYZ_BIT|TDFX_RGBA_BIT].vertex_format; - fxMesa->vertex_stride_shift = setup_tab[(TDFX_XYZ_BIT| - TDFX_RGBA_BIT)].vertex_stride_shift; + fxMesa->verts = ALIGN_MALLOC(size * sizeof(tdfxVertex), 32); + fxMesa->vertexFormat = TDFX_LAYOUT_TINY; fxMesa->SetupIndex = TDFX_XYZ_BIT|TDFX_RGBA_BIT; } diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vb.h b/src/mesa/drivers/dri/tdfx/tdfx_vb.h index 7cb90f5a5b6..4e5f0b25284 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_vb.h +++ b/src/mesa/drivers/dri/tdfx/tdfx_vb.h @@ -39,7 +39,8 @@ #define TDFX_TEX1_BIT 0x8 #define TDFX_TEX0_BIT 0x10 #define TDFX_PTEX_BIT 0x20 -#define TDFX_MAX_SETUP 0x40 +#define TDFX_FOGC_BIT 0x40 +#define TDFX_MAX_SETUP 0x80 #define _TDFX_NEW_RASTERSETUP (_NEW_TEXTURE | \ _DD_NEW_SEPARATE_SPECULAR | \ diff --git a/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h b/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h index e51e1f561ae..9b780761f42 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h +++ b/src/mesa/drivers/dri/tdfx/tdfx_vbtmp.h @@ -1,19 +1,54 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * Copyright (C) 1999-2002 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. + */ + +/* Authors: + * Keith Whitwell + * Daniel Borca + */ + + +#define VIEWPORT_X(dst,x) dst = s[0] * x + s[12] +#define VIEWPORT_Y(dst,y) dst = s[5] * y + s[13] +#define VIEWPORT_Z(dst,z) dst = s[10] * z + s[14] -#if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, - void *dest, - GLuint stride ) + void *dest ) { tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + GLuint tmu0_source = fxMesa->tmu_source[0]; + GLuint tmu1_source = fxMesa->tmu_source[1]; GLfloat (*tc0)[4], (*tc1)[4]; GLfloat (*col)[4]; GLuint tc0_stride, tc1_stride, col_stride; - GLuint tc0_size, tc1_size; + GLuint tc0_size, tc1_size, col_size; GLfloat (*proj)[4] = VB->NdcPtr->data; GLuint proj_stride = VB->NdcPtr->stride; + GLfloat (*fog)[4]; + GLuint fog_stride; tdfxVertex *v = (tdfxVertex *)dest; GLfloat u0scale,v0scale,u1scale,v1scale; const GLubyte *mask = VB->ClipMask; @@ -21,30 +56,34 @@ static void TAG(emit)( GLcontext *ctx, int i; /* fprintf(stderr, "%s\n", __FUNCTION__); */ - ASSERT(stride > 16); - if (IND & TDFX_TEX0_BIT) { - tc0_stride = VB->TexCoordPtr[0]->stride; - tc0 = VB->TexCoordPtr[0]->data; + tc0_stride = VB->TexCoordPtr[tmu0_source]->stride; + tc0 = VB->TexCoordPtr[tmu0_source]->data; u0scale = fxMesa->sScale0; v0scale = fxMesa->tScale0; if (IND & TDFX_PTEX_BIT) - tc0_size = VB->TexCoordPtr[0]->size; + tc0_size = VB->TexCoordPtr[tmu0_source]->size; } if (IND & TDFX_TEX1_BIT) { - tc1 = VB->TexCoordPtr[1]->data; - tc1_stride = VB->TexCoordPtr[1]->stride; + tc1 = VB->TexCoordPtr[tmu1_source]->data; + tc1_stride = VB->TexCoordPtr[tmu1_source]->stride; u1scale = fxMesa->sScale1; v1scale = fxMesa->tScale1; if (IND & TDFX_PTEX_BIT) - tc1_size = VB->TexCoordPtr[1]->size; + tc1_size = VB->TexCoordPtr[tmu1_source]->size; } if (IND & TDFX_RGBA_BIT) { col = VB->ColorPtr[0]->data; col_stride = VB->ColorPtr[0]->stride; + col_size = VB->ColorPtr[0]->size; + } + + if (IND & TDFX_FOGC_BIT) { + fog = VB->FogCoordPtr->data; + fog_stride = VB->FogCoordPtr->stride; } { @@ -58,153 +97,65 @@ static void TAG(emit)( GLcontext *ctx, tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + start * tc1_stride); if (IND & TDFX_RGBA_BIT) STRIDE_4F(col, start * col_stride); + if (IND & TDFX_FOGC_BIT) + STRIDE_4F(fog, start * fog_stride); } - for (i=start; i < end; i++, v = (tdfxVertex *)((GLubyte *)v + stride)) { + for (i=start; i < end; i++, v++) { if (IND & TDFX_XYZ_BIT) { if (mask[i] == 0) { /* unclipped */ - v->v.x = s[0] * proj[0][0] + s[12]; - v->v.y = s[5] * proj[0][1] + s[13]; - v->v.z = s[10] * proj[0][2] + s[14]; - v->v.rhw = proj[0][3]; + VIEWPORT_X(v->x, proj[0][0]); + VIEWPORT_Y(v->y, proj[0][1]); + VIEWPORT_Z(v->z, proj[0][2]); + v->rhw = proj[0][3]; } else { /* clipped */ - v->v.rhw = 1.0; + v->rhw = 1.0; } proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); } if (IND & TDFX_RGBA_BIT) { - GLubyte *b = (GLubyte *)((GLuint *)v + 4); - UNCLAMPED_FLOAT_TO_UBYTE(b[0], col[0][2]); - UNCLAMPED_FLOAT_TO_UBYTE(b[1], col[0][1]); - UNCLAMPED_FLOAT_TO_UBYTE(b[2], col[0][0]); - UNCLAMPED_FLOAT_TO_UBYTE(b[3], col[0][3]); + UNCLAMPED_FLOAT_TO_UBYTE(v->color[0], col[0][2]); + UNCLAMPED_FLOAT_TO_UBYTE(v->color[1], col[0][1]); + UNCLAMPED_FLOAT_TO_UBYTE(v->color[2], col[0][0]); + if (col_size == 4) { + UNCLAMPED_FLOAT_TO_UBYTE(v->color[3], col[0][3]); + } else { + v->color[3] = 255; + } STRIDE_4F(col, col_stride); } + if (IND & TDFX_FOGC_BIT) { + v->fog = CLAMP(fog[0][0], 0.0f, 1.0f); + STRIDE_4F(fog, fog_stride); + } if (IND & TDFX_TEX0_BIT) { - GLfloat w = v->v.rhw; + GLfloat w = v->rhw; + v->tu0 = tc0[0][0] * u0scale * w; + v->tv0 = tc0[0][1] * v0scale * w; if (IND & TDFX_PTEX_BIT) { - v->pv.tu0 = tc0[0][0] * u0scale * w; - v->pv.tv0 = tc0[0][1] * v0scale * w; - v->pv.tq0 = w; + v->tq0 = w; if (tc0_size == 4) - v->pv.tq0 = tc0[0][3] * w; - } - else { - v->v.tu0 = tc0[0][0] * u0scale * w; - v->v.tv0 = tc0[0][1] * v0scale * w; + v->tq0 = tc0[0][3] * w; } tc0 = (GLfloat (*)[4])((GLubyte *)tc0 + tc0_stride); } if (IND & TDFX_TEX1_BIT) { - GLfloat w = v->v.rhw; + GLfloat w = v->rhw; + v->tu1 = tc1[0][0] * u1scale * w; + v->tv1 = tc1[0][1] * v1scale * w; if (IND & TDFX_PTEX_BIT) { - v->pv.tu1 = tc1[0][0] * u1scale * w; - v->pv.tv1 = tc1[0][1] * v1scale * w; - v->pv.tq1 = w; + v->tq1 = w; if (tc1_size == 4) - v->pv.tq1 = tc1[0][3] * w; - } - else { - v->v.tu1 = tc1[0][0] * u1scale * w; - v->v.tv1 = tc1[0][1] * v1scale * w; + v->tq1 = tc1[0][3] * w; } tc1 = (GLfloat (*)[4])((GLubyte *)tc1 + tc1_stride); } } } } -#else -#if (IND & TDFX_XYZ_BIT) -static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, - void *dest, GLuint stride ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLfloat (*col)[4]; - GLuint col_stride; - GLfloat (*proj)[4] = VB->NdcPtr->data; - GLuint proj_stride = VB->NdcPtr->stride; - GLfloat *v = (GLfloat *)dest; - const GLubyte *mask = VB->ClipMask; - const GLfloat *s = fxMesa->hw_viewport; - int i; - -/* fprintf(stderr, "%s %d..%d dest %p stride %d\n", __FUNCTION__, */ -/* start, end, dest, stride); */ - - ASSERT(fxMesa->SetupIndex == (TDFX_XYZ_BIT|TDFX_RGBA_BIT)); - ASSERT(stride == 16); - - col = VB->ColorPtr[0]->data; - col_stride = VB->ColorPtr[0]->stride; - ASSERT(VB->ColorPtr[0]->Type == GL_UNSIGNED_BYTE); - /* Pack what's left into a 4-dword vertex. Color is in a different - * place, and there is no 'w' coordinate. - */ - { - if (start) { - proj = (GLfloat (*)[4])((GLubyte *)proj + start * proj_stride); - STRIDE_4F(col, start * col_stride); - } - - for (i=start; i < end; i++, v+=4) { - if (mask[i] == 0) { - v[0] = s[0] * proj[0][0] + s[12]; - v[1] = s[5] * proj[0][1] + s[13]; - v[2] = s[10] * proj[0][2] + s[14]; - } - proj = (GLfloat (*)[4])((GLubyte *)proj + proj_stride); - { - GLubyte *b = (GLubyte *)&v[3]; - UNCLAMPED_FLOAT_TO_UBYTE(b[0], col[0][2]); - UNCLAMPED_FLOAT_TO_UBYTE(b[1], col[0][1]); - UNCLAMPED_FLOAT_TO_UBYTE(b[2], col[0][0]); - UNCLAMPED_FLOAT_TO_UBYTE(b[3], col[0][3]); - STRIDE_4F(col, col_stride); - } - } - } -} -#else -static void TAG(emit)( GLcontext *ctx, GLuint start, GLuint end, - void *dest, GLuint stride ) -{ - tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); - struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - GLfloat (*col)[4]; - GLuint col_stride; - GLfloat *v = (GLfloat *)dest; - int i; - - col = VB->ColorPtr[0]->data; - col_stride = VB->ColorPtr[0]->stride; - - if (start) - STRIDE_4F(col, col_stride * start); - - /* Need to figure out where color is: - */ - if (fxMesa->SetupIndex & TDFX_W_BIT ) - v += 4; - else - v += 3; - - for (i=start; i < end; i++, STRIDE_F(v, stride)) { - GLubyte *b = (GLubyte *)v; - UNCLAMPED_FLOAT_TO_UBYTE(b[0], col[0][2]); - UNCLAMPED_FLOAT_TO_UBYTE(b[1], col[0][1]); - UNCLAMPED_FLOAT_TO_UBYTE(b[2], col[0][0]); - UNCLAMPED_FLOAT_TO_UBYTE(b[3], col[0][3]); - STRIDE_4F(col, col_stride); - } -} -#endif -#endif - -#if (IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT) static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) { @@ -231,6 +182,7 @@ static GLboolean TAG(check_tex_sizes)( GLcontext *ctx ) return GL_TRUE; } + static void TAG(interp)( GLcontext *ctx, GLfloat t, GLuint edst, GLuint eout, GLuint ein, @@ -238,69 +190,44 @@ static void TAG(interp)( GLcontext *ctx, { tdfxContextPtr fxMesa = TDFX_CONTEXT( ctx ); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - const GLuint shift = fxMesa->vertex_stride_shift; const GLfloat *dstclip = VB->ClipPtr->data[edst]; const GLfloat oow = (dstclip[3] == 0.0F) ? 1.0F : (1.0F / dstclip[3]); const GLfloat *s = fxMesa->hw_viewport; - GLubyte *tdfxverts = (GLubyte *)fxMesa->verts; - tdfxVertex *dst = (tdfxVertex *) (tdfxverts + (edst << shift)); - const tdfxVertex *out = (const tdfxVertex *) (tdfxverts + (eout << shift)); - const tdfxVertex *in = (const tdfxVertex *) (tdfxverts + (ein << shift)); - const GLfloat wout = 1.0F / out->v.rhw; - const GLfloat win = 1.0F / in->v.rhw; - - dst->v.x = s[0] * dstclip[0] * oow + s[12]; - dst->v.y = s[5] * dstclip[1] * oow + s[13]; - dst->v.z = s[10] * dstclip[2] * oow + s[14]; - - if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) { - dst->v.rhw = oow; - - INTERP_UB( t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0] ); - INTERP_UB( t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1] ); - INTERP_UB( t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2] ); - INTERP_UB( t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3] ); + tdfxVertex *dst = fxMesa->verts + edst; + const tdfxVertex *out = fxMesa->verts + eout; + const tdfxVertex *in = fxMesa->verts + ein; + const GLfloat wout = oow / out->rhw; + const GLfloat win = oow / in->rhw; + + VIEWPORT_X(dst->x, dstclip[0] * oow); + VIEWPORT_Y(dst->y, dstclip[1] * oow); + VIEWPORT_Z(dst->z, dstclip[2] * oow); + dst->rhw = oow; + + INTERP_UB( t, dst->color[0], out->color[0], in->color[0] ); + INTERP_UB( t, dst->color[1], out->color[1], in->color[1] ); + INTERP_UB( t, dst->color[2], out->color[2], in->color[2] ); + INTERP_UB( t, dst->color[3], out->color[3], in->color[3] ); + + if (IND & TDFX_FOGC_BIT) { + INTERP_F( t, dst->fog, out->fog, in->fog ); + } - if (IND & TDFX_TEX0_BIT) { - if (IND & TDFX_PTEX_BIT) { - INTERP_F( t, dst->pv.tu0, out->pv.tu0 * wout, in->pv.tu0 * win ); - INTERP_F( t, dst->pv.tv0, out->pv.tv0 * wout, in->pv.tv0 * win ); - INTERP_F( t, dst->pv.tq0, out->pv.tq0 * wout, in->pv.tq0 * win ); - dst->pv.tu0 *= oow; - dst->pv.tv0 *= oow; - dst->pv.tq0 *= oow; - } else { - INTERP_F( t, dst->v.tu0, out->v.tu0 * wout, in->v.tu0 * win ); - INTERP_F( t, dst->v.tv0, out->v.tv0 * wout, in->v.tv0 * win ); - dst->v.tu0 *= oow; - dst->v.tv0 *= oow; - } - } - if (IND & TDFX_TEX1_BIT) { - if (IND & TDFX_PTEX_BIT) { - INTERP_F( t, dst->pv.tu1, out->pv.tu1 * wout, in->pv.tu1 * win ); - INTERP_F( t, dst->pv.tv1, out->pv.tv1 * wout, in->pv.tv1 * win ); - INTERP_F( t, dst->pv.tq1, out->pv.tq1 * wout, in->pv.tq1 * win ); - dst->pv.tu1 *= oow; - dst->pv.tv1 *= oow; - dst->pv.tq1 *= oow; - } else { - INTERP_F( t, dst->v.tu1, out->v.tu1 * wout, in->v.tu1 * win ); - INTERP_F( t, dst->v.tv1, out->v.tv1 * wout, in->v.tv1 * win ); - dst->v.tu1 *= oow; - dst->v.tv1 *= oow; - } + if (IND & TDFX_TEX0_BIT) { + INTERP_F( t, dst->tu0, out->tu0 * wout, in->tu0 * win ); + INTERP_F( t, dst->tv0, out->tv0 * wout, in->tv0 * win ); + if (IND & TDFX_PTEX_BIT) { + INTERP_F( t, dst->tq0, out->tq0 * wout, in->tq0 * win ); } - } else { - /* 4-dword vertex. Color is in v[3] and there is no oow coordinate. - */ - INTERP_UB( t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0] ); - INTERP_UB( t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1] ); - INTERP_UB( t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2] ); - INTERP_UB( t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3] ); + } + if (IND & TDFX_TEX1_BIT) { + INTERP_F( t, dst->tu1, out->tu1 * wout, in->tu1 * win ); + INTERP_F( t, dst->tv1, out->tv1 * wout, in->tv1 * win ); + if (IND & TDFX_PTEX_BIT) { + INTERP_F( t, dst->tq1, out->tq1 * wout, in->tq1 * win ); + } } } -#endif static void TAG(init)( void ) @@ -308,50 +235,30 @@ static void TAG(init)( void ) /* fprintf(stderr, "%s\n", __FUNCTION__); */ setup_tab[IND].emit = TAG(emit); - -#if ((IND & TDFX_XYZ_BIT) && (IND & TDFX_RGBA_BIT)) setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes); setup_tab[IND].interp = TAG(interp); - - if (IND & (TDFX_W_BIT|TDFX_TEX0_BIT|TDFX_TEX1_BIT)) - setup_tab[IND].copy_pv = copy_pv_rgba4; - else - setup_tab[IND].copy_pv = copy_pv_rgba3; - + setup_tab[IND].copy_pv = copy_pv; if (IND & TDFX_TEX1_BIT) { if (IND & TDFX_PTEX_BIT) { - setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; - setup_tab[IND].vertex_size = 12; - setup_tab[IND].vertex_stride_shift = 6; + setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJ2; } else { setup_tab[IND].vertex_format = TDFX_LAYOUT_MULTI; - setup_tab[IND].vertex_size = 10; - setup_tab[IND].vertex_stride_shift = 6; } } else if (IND & TDFX_TEX0_BIT) { if (IND & TDFX_PTEX_BIT) { - setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJECT; - setup_tab[IND].vertex_size = 12; - setup_tab[IND].vertex_stride_shift = 6; + setup_tab[IND].vertex_format = TDFX_LAYOUT_PROJ1; } else { setup_tab[IND].vertex_format = TDFX_LAYOUT_SINGLE; - setup_tab[IND].vertex_size = 8; - setup_tab[IND].vertex_stride_shift = 5; } } else if (IND & TDFX_W_BIT) { setup_tab[IND].vertex_format = TDFX_LAYOUT_NOTEX; - setup_tab[IND].vertex_size = 6; - setup_tab[IND].vertex_stride_shift = 5; } else { setup_tab[IND].vertex_format = TDFX_LAYOUT_TINY; - setup_tab[IND].vertex_size = 4; - setup_tab[IND].vertex_stride_shift = 4; } -#endif } -- 2.30.2