From: Ian Romanick Date: Mon, 29 Aug 2005 15:43:02 +0000 (+0000) Subject: Implement GL_ARB_texture_env_combine, GL_EXT_texture_env_combine, and X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=f0d0e5099417796b629ad76e4e2fc19baa31c38d;p=mesa.git Implement GL_ARB_texture_env_combine, GL_EXT_texture_env_combine, and GL_ARB_texture_env_crossbar for i810. This passes both demos/texenv and all of glean's texCombine tests. --- diff --git a/src/mesa/drivers/dri/i810/i810_3d_reg.h b/src/mesa/drivers/dri/i810/i810_3d_reg.h index dade1a826c7..7cc59d5c86a 100644 --- a/src/mesa/drivers/dri/i810/i810_3d_reg.h +++ b/src/mesa/drivers/dri/i810/i810_3d_reg.h @@ -254,30 +254,30 @@ /* GFXRENDERSTATE_MAP_ALPHA_BLEND_STAGES, p132 */ -#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24)) -#define MA_STAGE_SHIFT 20 -#define MA_STAGE_0 (0<<20) -#define MA_STAGE_1 (1<<20) -#define MA_STAGE_2 (2<<20) -#define MA_UPDATE_ARG1 (1<<18) -#define MA_ARG1_MASK ((0x7<<15)|(0x1<<13)) -#define MA_ARG1_ALPHA_FACTOR (0x1<<15) -#define MA_ARG1_ITERATED_ALPHA (0x3<<15) -#define MA_ARG1_CURRENT_ALPHA (0x5<<15) -#define MA_ARG1_TEX0_ALPHA (0x6<<15) -#define MA_ARG1_TEX1_ALPHA (0x7<<15) -#define MA_ARG1_INVERT (0x1<<13) -#define MA_ARG1_DONT_INVERT (0x0<<13) -#define MA_UPDATE_ARG2 (1<<12) -#define MA_ARG2_MASK ((0x7<<8)|(0x1<<6)) -#define MA_ARG2_ALPHA_FACTOR (0x1<<8) -#define MA_ARG2_ITERATED_ALPHA (0x3<<8) -#define MA_ARG2_CURRENT_ALPHA (0x5<<8) -#define MA_ARG2_TEX0_ALPHA (0x6<<8) -#define MA_ARG2_TEX1_ALPHA (0x7<<8) -#define MA_ARG2_INVERT (0x1<<6) -#define MA_ARG2_DONT_INVERT (0x0<<6) -#define MA_UPDATE_OP (1<<5) +#define GFX_OP_MAP_ALPHA_STAGES ((0x3<<29)|(0x1<<24)) +#define MA_STAGE_SHIFT 20 +#define MA_STAGE_0 (0<<20) +#define MA_STAGE_1 (1<<20) +#define MA_STAGE_2 (2<<20) + +#define MA_ARG_ONE (0x0<<2) +#define MA_ARG_ALPHA_FACTOR (0x1<<2) +#define MA_ARG_ITERATED_ALPHA (0x3<<2) +#define MA_ARG_CURRENT_ALPHA (0x5<<2) +#define MA_ARG_TEX0_ALPHA (0x6<<2) +#define MA_ARG_TEX1_ALPHA (0x7<<2) +#define MA_ARG_INVERT (0x1) +#define MA_ARG_DONT_INVERT (0x0) + +#define MA_UPDATE_ARG1 (1<<18) +#define MA_ARG1_SHIFT 13 +#define MA_ARG1_MASK (0x1d << MA_ARG1_SHIFT) + +#define MA_UPDATE_ARG2 (1<<12) +#define MA_ARG2_SHIFT 6 +#define MA_ARG2_MASK (0x1d << MA_ARG2_SHIFT) + +#define MA_UPDATE_OP (1<<5) #define MA_OP_MASK (0xf) #define MA_OP_ARG1 (0x1) #define MA_OP_ARG2 (0x2) @@ -290,64 +290,59 @@ #define MA_OP_LIN_BLEND_ALPHA_FACTOR (0xa) #define MA_OP_LIN_BLEND_TEX0_ALPHA (0x10) #define MA_OP_LIN_BLEND_TEX1_ALPHA (0x11) +#define MA_OP_SUBTRACT (0x14) /* GFXRENDERSTATE_MAP_COLOR_BLEND_STAGES, p129 */ -#define GFX_OP_MAP_COLOR_STAGES ((0x3<<29)|(0x0<<24)) -#define MC_STAGE_SHIFT 20 -#define MC_STAGE_0 (0<<20) -#define MC_STAGE_1 (1<<20) -#define MC_STAGE_2 (2<<20) -#define MC_UPDATE_DEST (1<<19) -#define MC_DEST_MASK (1<<18) -#define MC_DEST_CURRENT (0<<18) -#define MC_DEST_ACCUMULATOR (1<<18) -#define MC_UPDATE_ARG1 (1<<17) -#define MC_ARG1_MASK ((0x7<<14)|(0x1<<13)|(0x1<<12)) -#define MC_ARG1_ONE (0x0<<14) -#define MC_ARG1_COLOR_FACTOR (0x1<<14) -#define MC_ARG1_ACCUMULATOR (0x2<<14) -#define MC_ARG1_ITERATED_COLOR (0x3<<14) -#define MC_ARG1_SPECULAR_COLOR (0x4<<14) -#define MC_ARG1_CURRENT_COLOR (0x5<<14) -#define MC_ARG1_TEX0_COLOR (0x6<<14) -#define MC_ARG1_TEX1_COLOR (0x7<<14) -#define MC_ARG1_DONT_REPLICATE_ALPHA (0x0<<13) -#define MC_ARG1_REPLICATE_ALPHA (0x1<<13) -#define MC_ARG1_DONT_INVERT (0x0<<12) -#define MC_ARG1_INVERT (0x1<<12) -#define MC_UPDATE_ARG2 (1<<11) -#define MC_ARG2_MASK ((0x7<<8)|(0x1<<7)|(0x1<<6)) -#define MC_ARG2_ONE (0x0<<8) -#define MC_ARG2_COLOR_FACTOR (0x1<<8) -#define MC_ARG2_ACCUMULATOR (0x2<<8) -#define MC_ARG2_ITERATED_COLOR (0x3<<8) -#define MC_ARG2_SPECULAR_COLOR (0x4<<8) -#define MC_ARG2_CURRENT_COLOR (0x5<<8) -#define MC_ARG2_TEX0_COLOR (0x6<<8) -#define MC_ARG2_TEX1_COLOR (0x7<<8) -#define MC_ARG2_DONT_REPLICATE_ALPHA (0x0<<7) -#define MC_ARG2_REPLICATE_ALPHA (0x1<<7) -#define MC_ARG2_DONT_INVERT (0x0<<6) -#define MC_ARG2_INVERT (0x1<<6) -#define MC_UPDATE_OP (1<<5) -#define MC_OP_MASK (0xf) -#define MC_OP_DISABLE (0x0) -#define MC_OP_ARG1 (0x1) -#define MC_OP_ARG2 (0x2) -#define MC_OP_MODULATE (0x3) -#define MC_OP_MODULATE_X2 (0x4) -#define MC_OP_MODULATE_X4 (0x5) -#define MC_OP_ADD (0x6) -#define MC_OP_ADD_SIGNED (0x7) -#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8) -#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa) -#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10) -#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11) -#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12) -#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13) -#define MC_OP_SUBTRACT (0x14) +#define GFX_OP_MAP_COLOR_STAGES ((0x3<<29)|(0x0<<24)) +#define MC_STAGE_SHIFT 20 +#define MC_STAGE_0 (0<<20) +#define MC_STAGE_1 (1<<20) +#define MC_STAGE_2 (2<<20) +#define MC_UPDATE_DEST (1<<19) +#define MC_DEST_MASK (1<<18) +#define MC_DEST_CURRENT (0<<18) +#define MC_DEST_ACCUMULATOR (1<<18) + +#define MC_ARG_ONE (0x0<<2) +#define MC_ARG_COLOR_FACTOR (0x1<<2) +#define MC_ARG_ACCUMULATOR (0x2<<2) +#define MC_ARG_ITERATED_COLOR (0x3<<2) +#define MC_ARG_SPECULAR_COLOR (0x4<<2) +#define MC_ARG_CURRENT_COLOR (0x5<<2) +#define MC_ARG_TEX0_COLOR (0x6<<2) +#define MC_ARG_TEX1_COLOR (0x7<<2) +#define MC_ARG_DONT_REPLICATE_ALPHA (0x0<<1) +#define MC_ARG_REPLICATE_ALPHA (0x1<<1) +#define MC_ARG_DONT_INVERT (0x0) +#define MC_ARG_INVERT (0x1) + +#define MC_UPDATE_ARG1 (1<<17) +#define MC_ARG1_SHIFT 12 +#define MC_ARG1_MASK (0x1f << MC_ARG1_SHIFT) + +#define MC_UPDATE_ARG2 (1<<11) +#define MC_ARG2_SHIFT 6 +#define MC_ARG2_MASK (0x1f << MC_ARG2_SHIFT) + +#define MC_UPDATE_OP (1<<5) +#define MC_OP_MASK (0xf) +#define MC_OP_DISABLE (0x0) +#define MC_OP_ARG1 (0x1) +#define MC_OP_ARG2 (0x2) +#define MC_OP_MODULATE (0x3) +#define MC_OP_MODULATE_X2 (0x4) +#define MC_OP_MODULATE_X4 (0x5) +#define MC_OP_ADD (0x6) +#define MC_OP_ADD_SIGNED (0x7) +#define MC_OP_LIN_BLEND_ITER_ALPHA (0x8) +#define MC_OP_LIN_BLEND_ALPHA_FACTOR (0xa) +#define MC_OP_LIN_BLEND_TEX0_ALPHA (0x10) +#define MC_OP_LIN_BLEND_TEX1_ALPHA (0x11) +#define MC_OP_LIN_BLEND_TEX0_COLOR (0x12) +#define MC_OP_LIN_BLEND_TEX1_COLOR (0x13) +#define MC_OP_SUBTRACT (0x14) /* GFXRENDERSTATE_MAP_PALETTE_LOAD, p128 * diff --git a/src/mesa/drivers/dri/i810/i810context.c b/src/mesa/drivers/dri/i810/i810context.c index 47c41c5db28..fd80e7675c4 100644 --- a/src/mesa/drivers/dri/i810/i810context.c +++ b/src/mesa/drivers/dri/i810/i810context.c @@ -73,7 +73,7 @@ int I810_DEBUG = (0); PUBLIC const char __driConfigOptions[] = { 0 }; const GLuint __driNConfigOptions = 0; -#define DRIVER_DATE "20050818" +#define DRIVER_DATE "20050821" static const GLubyte *i810GetString( GLcontext *ctx, GLenum name ) { @@ -125,9 +125,12 @@ const struct dri_extension card_extensions[] = { "GL_ARB_multitexture", NULL }, { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, { "GL_ARB_texture_env_add", NULL }, + { "GL_ARB_texture_env_combine", NULL }, + { "GL_ARB_texture_env_crossbar", NULL }, { "GL_ARB_texture_mirrored_repeat", NULL }, { "GL_EXT_stencil_wrap", NULL }, { "GL_EXT_texture_edge_clamp", NULL }, + { "GL_EXT_texture_env_combine", NULL }, { "GL_EXT_texture_lod_bias", NULL }, { "GL_MESA_ycbcr_texture", NULL }, { "GL_NV_blend_square", NULL }, diff --git a/src/mesa/drivers/dri/i810/i810state.c b/src/mesa/drivers/dri/i810/i810state.c index 62dc819b32b..c4662e89580 100644 --- a/src/mesa/drivers/dri/i810/i810state.c +++ b/src/mesa/drivers/dri/i810/i810state.c @@ -746,13 +746,13 @@ void i810InitState( GLcontext *ctx ) MC_UPDATE_DEST | MC_DEST_CURRENT | MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_ARG1_DONT_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | + ((MC_ARG_ITERATED_COLOR | + MC_ARG_DONT_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) | MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | + ((MC_ARG_ONE | + MC_ARG_DONT_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) | MC_UPDATE_OP | MC_OP_ARG1 ); @@ -761,13 +761,13 @@ void i810InitState( GLcontext *ctx ) MC_UPDATE_DEST | MC_DEST_CURRENT | MC_UPDATE_ARG1 | - MC_ARG1_ONE | - MC_ARG1_DONT_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | + ((MC_ARG_ONE | + MC_ARG_DONT_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) | MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | + ((MC_ARG_ONE | + MC_ARG_DONT_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) | MC_UPDATE_OP | MC_OP_DISABLE ); @@ -777,13 +777,13 @@ void i810InitState( GLcontext *ctx ) MC_UPDATE_DEST | MC_DEST_CURRENT | MC_UPDATE_ARG1 | - MC_ARG1_CURRENT_COLOR | - MC_ARG1_REPLICATE_ALPHA | - MC_ARG1_DONT_INVERT | + ((MC_ARG_CURRENT_COLOR | + MC_ARG_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG1_SHIFT) | MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_ARG2_DONT_REPLICATE_ALPHA | - MC_ARG2_DONT_INVERT | + ((MC_ARG_ONE | + MC_ARG_DONT_REPLICATE_ALPHA | + MC_ARG_DONT_INVERT) << MC_ARG2_SHIFT) | MC_UPDATE_OP | MC_OP_DISABLE ); @@ -791,11 +791,11 @@ void i810InitState( GLcontext *ctx ) imesa->Setup[I810_CTXREG_MA0] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 | MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_ARG1_DONT_INVERT | + ((MA_ARG_ITERATED_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) | MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | + ((MA_ARG_CURRENT_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) | MA_UPDATE_OP | MA_OP_ARG1 ); @@ -803,11 +803,11 @@ void i810InitState( GLcontext *ctx ) imesa->Setup[I810_CTXREG_MA1] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1 | MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_ARG1_DONT_INVERT | + ((MA_ARG_CURRENT_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) | MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | + ((MA_ARG_CURRENT_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) | MA_UPDATE_OP | MA_OP_ARG1 ); @@ -815,11 +815,11 @@ void i810InitState( GLcontext *ctx ) imesa->Setup[I810_CTXREG_MA2] = ( GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_2 | MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_ARG1_DONT_INVERT | + ((MA_ARG_CURRENT_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG1_SHIFT) | MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_ARG2_DONT_INVERT | + ((MA_ARG_CURRENT_ALPHA | + MA_ARG_DONT_INVERT) << MA_ARG2_SHIFT) | MA_UPDATE_OP | MA_OP_ARG1 ); diff --git a/src/mesa/drivers/dri/i810/i810texstate.c b/src/mesa/drivers/dri/i810/i810texstate.c index 10a15f961f6..6b6d1d727fc 100644 --- a/src/mesa/drivers/dri/i810/i810texstate.c +++ b/src/mesa/drivers/dri/i810/i810texstate.c @@ -132,620 +132,567 @@ static void i810SetTexImages( i810ContextPtr imesa, * Texture combine functions */ -#define I810_DISABLE 0 -#define I810_PASSTHRU 1 -#define I810_REPLACE 2 -#define I810_MODULATE 3 -#define I810_DECAL 4 -#define I810_BLEND 5 -#define I810_ALPHA_BLEND 6 -#define I810_ADD 7 -#define I810_MAX_COMBFUNC 8 - - -static GLuint i810_color_combine[][I810_MAX_COMBFUNC] = -{ - /* Unit 0: - */ - { - /* Disable combiner stage - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ), /* actually passthru */ - - /* Passthru - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ITERATED_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ), - - /* GL_REPLACE - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ), - - /* GL_MODULATE - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_MODULATE ), - - /* GL_DECAL - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | - MC_UPDATE_ARG2 | - MC_ARG2_TEX0_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX0_ALPHA ), - - /* GL_BLEND - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX0_COLOR ), - - /* GL_BLEND according to alpha - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX0_ALPHA ), - - /* GL_ADD - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_0 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX0_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ITERATED_COLOR | - MC_UPDATE_OP | - MC_OP_ADD ), - }, - - /* Unit 1: - */ - { - /* Disable combiner stage (Note: disables all subsequent stages) - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_ONE | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_DISABLE ), - - /* Passthru - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_CURRENT_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ), - - /* GL_REPLACE - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX1_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_ONE | - MC_UPDATE_OP | - MC_OP_ARG1 ), - - /* GL_MODULATE - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX1_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_CURRENT_COLOR | - MC_UPDATE_OP | - MC_OP_MODULATE ), - - /* GL_DECAL - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | - MC_UPDATE_ARG2 | - MC_ARG2_TEX1_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX1_ALPHA ), - - /* GL_BLEND - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_COLOR_FACTOR | - MC_UPDATE_ARG2 | - MC_ARG2_CURRENT_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX1_COLOR ), - - /* GL_BLEND according to alpha - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX1_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_CURRENT_COLOR | - MC_UPDATE_OP | - MC_OP_LIN_BLEND_TEX1_ALPHA ), - - /* GL_ADD - */ - ( GFX_OP_MAP_COLOR_STAGES | - MC_STAGE_1 | - MC_UPDATE_DEST | - MC_DEST_CURRENT | - MC_UPDATE_ARG1 | - MC_ARG1_TEX1_COLOR | - MC_UPDATE_ARG2 | - MC_ARG2_CURRENT_COLOR | - MC_UPDATE_OP | - MC_OP_ADD ), +static void set_color_stage( unsigned color, int stage, + i810ContextPtr imesa ) +{ + if ( color != imesa->Setup[I810_CTXREG_MC0 + stage] ) { + I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); + imesa->Setup[I810_CTXREG_MC0 + stage] = color; } -}; +} + -static GLuint i810_alpha_combine[][I810_MAX_COMBFUNC] = +static void set_alpha_stage( unsigned alpha, int stage, + i810ContextPtr imesa ) { - /* Unit 0: - */ - { - /* Disable combiner stage - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* Passthru - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* GL_REPLACE - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG2 ), - - /* GL_MODULATE - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_MODULATE ), - - /* GL_DECAL - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ALPHA_FACTOR | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* GL_BLEND - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ITERATED_ALPHA | - MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX0_ALPHA ), - - /* GL_BLEND according to alpha (same as above) - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ITERATED_ALPHA | - MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX0_ALPHA ), - - /* GL_ADD - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_0 | - MA_UPDATE_ARG1 | - MA_ARG1_ITERATED_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX0_ALPHA | - MA_UPDATE_OP | - MA_OP_ADD ), - }, - - /* Unit 1: - */ - { - /* Disable combiner stage - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* Passthru - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_CURRENT_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* GL_REPLACE - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX1_ALPHA | - MA_UPDATE_OP | - MA_OP_ARG2 ), - - /* GL_MODULATE - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX1_ALPHA | - MA_UPDATE_OP | - MA_OP_MODULATE ), - - /* GL_DECAL - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ALPHA_FACTOR | - MA_UPDATE_OP | - MA_OP_ARG1 ), - - /* GL_BLEND - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ITERATED_ALPHA | - MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX1_ALPHA ), - - /* GL_BLEND according to alpha (same as above) - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_ALPHA_FACTOR | - MA_UPDATE_ARG2 | - MA_ARG2_ITERATED_ALPHA | - MA_UPDATE_OP | - MA_OP_LIN_BLEND_TEX1_ALPHA ), - - /* GL_ADD - */ - ( GFX_OP_MAP_ALPHA_STAGES | - MA_STAGE_1 | - MA_UPDATE_ARG1 | - MA_ARG1_CURRENT_ALPHA | - MA_UPDATE_ARG2 | - MA_ARG2_TEX1_ALPHA | - MA_UPDATE_OP | - MA_OP_ADD ), + if ( alpha != imesa->Setup[I810_CTXREG_MA0 + stage] ) { + I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); + imesa->Setup[I810_CTXREG_MA0 + stage] = alpha; } - -}; +} +static const unsigned operand_modifiers[] = { + 0, MC_ARG_INVERT, + MC_ARG_REPLICATE_ALPHA, MC_ARG_INVERT | MC_ARG_REPLICATE_ALPHA +}; -static void i810UpdateTexEnv( GLcontext *ctx, GLuint unit ) +/** + * Configure the hardware bits for the specified texture environment. + * + * Configures the hardware bits for the texture environment state for the + * specified texture unit. As combine stages are added, the values pointed + * to by \c color_stage and \c alpha_stage are incremented. + * + * \param ctx GL context pointer. + * \param unit Texture unit to be added. + * \param color_stage Next available hardware color combine stage. + * \param alpha_stage Next available hardware alpha combine stage. + * + * \returns + * If the combine mode for the specified texture unit could be added without + * requiring a software fallback, \c GL_TRUE is returned. Otherwise, + * \c GL_FALSE is returned. + * + * \todo + * If the mode is (GL_REPLACE, GL_PREVIOUS), treat it as though the texture + * stage is disabled. That is, don't emit any combine stages. + * + * \todo + * Add support for ATI_texture_env_combine3 modes. This will require using + * two combine stages. + * + * \todo + * Add support for the missing \c GL_INTERPOLATE modes. This will require + * using all three combine stages. There is a comment in the function + * describing how this might work. + * + * \todo + * If, after all the combine stages have been emitted, a texture is never + * actually used, disable the texture unit. That should save texture some + * memory bandwidth. This won't happen in this function, but this seems like + * a reasonable place to make note of it. + */ +static GLboolean +i810UpdateTexEnvCombine( GLcontext *ctx, GLuint unit, + int * color_stage, int * alpha_stage ) { i810ContextPtr imesa = I810_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - const struct gl_texture_object *tObj = texUnit->_Current; - const GLuint format = tObj->Image[0][tObj->BaseLevel]->Format; + GLuint color_arg[3] = { + MC_ARG_ONE, MC_ARG_ONE, MC_ARG_ONE + }; + GLuint alpha_arg[3] = { + MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA, MA_ARG_ITERATED_ALPHA + }; + GLuint i; GLuint color_combine, alpha_combine; + const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; + const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; + GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; + GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; - switch (texUnit->EnvMode) { - case GL_REPLACE: - if (format == GL_ALPHA) { - color_combine = i810_color_combine[unit][I810_PASSTHRU]; - alpha_combine = i810_alpha_combine[unit][I810_REPLACE]; - } else if (format == GL_LUMINANCE || format == GL_RGB) { - color_combine = i810_color_combine[unit][I810_REPLACE]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; - } else { - color_combine = i810_color_combine[unit][I810_REPLACE]; - alpha_combine = i810_alpha_combine[unit][I810_REPLACE]; - } - break; - case GL_MODULATE: - if (format == GL_ALPHA) { - color_combine = i810_color_combine[unit][I810_PASSTHRU]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; - } else { - color_combine = i810_color_combine[unit][I810_MODULATE]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + if ( !texUnit->_ReallyEnabled ) { + return GL_TRUE; + } + + + if ((*color_stage >= 3) || (*alpha_stage >= 3)) { + return GL_FALSE; + } + + + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + + for ( i = 0 ; i < numColorArgs ; i++ ) { + unsigned op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; + assert(op >= 0); + assert(op <= 3); + switch ( texUnit->_CurrentCombine->SourceRGB[i] ) { + case GL_TEXTURE0: + color_arg[i] = MC_ARG_TEX0_COLOR; + break; + case GL_TEXTURE1: + color_arg[i] = MC_ARG_TEX1_COLOR; + break; + case GL_TEXTURE: + color_arg[i] = (unit == 0) + ? MC_ARG_TEX0_COLOR : MC_ARG_TEX1_COLOR; + break; + case GL_CONSTANT: + color_arg[i] = MC_ARG_COLOR_FACTOR; + break; + case GL_PRIMARY_COLOR: + color_arg[i] = MC_ARG_ITERATED_COLOR; + break; + case GL_PREVIOUS: + color_arg[i] = (unit == 0) + ? MC_ARG_ITERATED_COLOR : MC_ARG_CURRENT_COLOR; + break; + case GL_ZERO: + /* Toggle the low bit of the op value. The is the 'invert' bit, + * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op. + */ + op ^= 1; + + /*FALLTHROUGH*/ + + case GL_ONE: + color_arg[i] = MC_ARG_ONE; + break; + default: + return GL_FALSE; } - break; - case GL_DECAL: - switch (format) { - case GL_RGBA: - color_combine = i810_color_combine[unit][I810_ALPHA_BLEND]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + color_arg[i] |= operand_modifiers[op]; + } + + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + unsigned op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; + assert(op >= 0); + assert(op <= 1); + switch ( texUnit->_CurrentCombine->SourceA[i] ) { + case GL_TEXTURE0: + alpha_arg[i] = MA_ARG_TEX0_ALPHA; + break; + case GL_TEXTURE1: + alpha_arg[i] = MA_ARG_TEX1_ALPHA; break; - case GL_RGB: - color_combine = i810_color_combine[unit][I810_REPLACE]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + case GL_TEXTURE: + alpha_arg[i] = (unit == 0) + ? MA_ARG_TEX0_ALPHA : MA_ARG_TEX1_ALPHA; break; - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - color_combine = i810_color_combine[unit][I810_PASSTHRU]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + case GL_CONSTANT: + alpha_arg[i] = MA_ARG_ALPHA_FACTOR; + break; + case GL_PRIMARY_COLOR: + alpha_arg[i] = MA_ARG_ITERATED_ALPHA; + break; + case GL_PREVIOUS: + alpha_arg[i] = (unit == 0) + ? MA_ARG_ITERATED_ALPHA : MA_ARG_CURRENT_ALPHA; + break; + case GL_ZERO: + /* Toggle the low bit of the op value. The is the 'invert' bit, + * and it acts to convert GL_ZERO+op to the equivalent GL_ONE+op. + */ + op ^= 1; + + /*FALLTHROUGH*/ + + case GL_ONE: + if (i != 2) { + return GL_FALSE; + } + + alpha_arg[i] = MA_ARG_ONE; break; - case GL_COLOR_INDEX: default: - return; + return GL_FALSE; } + + alpha_arg[i] |= operand_modifiers[op]; + } + + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->_CurrentCombine->ModeRGB ) { + case GL_REPLACE: + color_combine = MC_OP_ARG1; + break; + case GL_MODULATE: + color_combine = MC_OP_MODULATE + RGBshift; + RGBshift = 0; + break; + case GL_ADD: + color_combine = MC_OP_ADD; + break; + case GL_ADD_SIGNED: + color_combine = MC_OP_ADD_SIGNED; break; + case GL_SUBTRACT: + color_combine = MC_OP_SUBTRACT; + break; + case GL_INTERPOLATE: + /* For interpolation, the i810 hardware has some limitations. It + * can't handle using the secondary or diffuse color (diffuse alpha + * is okay) for the third argument. + * + * It is possible to emulate the missing modes by using multiple + * combine stages. Unfortunately it requires all three stages to + * emulate a single interpolate stage. The (arg0*arg2) portion is + * done in stage zero and writes to MC_DEST_ACCUMULATOR. The + * (arg1*(1-arg2)) portion is done in stage 1, and the final stage is + * (MC_ARG1_ACCUMULATOR | MC_ARG2_CURRENT_COLOR | MC_OP_ADD). + * + * It can also be done without using the accumulator by rearranging + * the equation as (arg1 + (arg2 * (arg0 - arg1))). Too bad the i810 + * doesn't support the MODULATE_AND_ADD mode that the i830 supports. + * If it did, the interpolate could be done in only two stages. + */ + + if ( (color_arg[2] & MC_ARG_INVERT) != 0 ) { + unsigned temp = color_arg[0]; + + color_arg[0] = color_arg[1]; + color_arg[1] = temp; + color_arg[2] &= ~MC_ARG_INVERT; + } + + switch (color_arg[2]) { + case (MC_ARG_ONE): + case (MC_ARG_ONE | MC_ARG_REPLICATE_ALPHA): + color_combine = MC_OP_ARG1; + color_arg[1] = MC_ARG_ONE; + break; + + case (MC_ARG_COLOR_FACTOR): + return GL_FALSE; + + case (MC_ARG_COLOR_FACTOR | MC_ARG_REPLICATE_ALPHA): + color_combine = MC_OP_LIN_BLEND_ALPHA_FACTOR; + break; + + case (MC_ARG_ITERATED_COLOR): + return GL_FALSE; + + case (MC_ARG_ITERATED_COLOR | MC_ARG_REPLICATE_ALPHA): + color_combine = MC_OP_LIN_BLEND_ITER_ALPHA; + break; + + case (MC_ARG_SPECULAR_COLOR): + case (MC_ARG_SPECULAR_COLOR | MC_ARG_REPLICATE_ALPHA): + return GL_FALSE; - case GL_BLEND: - switch (format) { - case GL_RGB: - case GL_LUMINANCE: - color_combine = i810_color_combine[unit][I810_BLEND]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + case (MC_ARG_TEX0_COLOR): + color_combine = MC_OP_LIN_BLEND_TEX0_COLOR; break; - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - color_combine = i810_color_combine[unit][I810_BLEND]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + + case (MC_ARG_TEX0_COLOR | MC_ARG_REPLICATE_ALPHA): + color_combine = MC_OP_LIN_BLEND_TEX0_ALPHA; break; - case GL_ALPHA: - color_combine = i810_color_combine[unit][I810_PASSTHRU]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + + case (MC_ARG_TEX1_COLOR): + color_combine = MC_OP_LIN_BLEND_TEX1_COLOR; break; - case GL_INTENSITY: - color_combine = i810_color_combine[unit][I810_BLEND]; - alpha_combine = i810_alpha_combine[unit][I810_BLEND]; + + case (MC_ARG_TEX1_COLOR | MC_ARG_REPLICATE_ALPHA): + color_combine = MC_OP_LIN_BLEND_TEX1_ALPHA; break; - case GL_COLOR_INDEX: + default: - return; + return GL_FALSE; } break; + default: + return GL_FALSE; + } + + + switch ( texUnit->_CurrentCombine->ModeA ) { + case GL_REPLACE: + alpha_combine = MA_OP_ARG1; + break; + case GL_MODULATE: + alpha_combine = MA_OP_MODULATE + Ashift; + Ashift = 0; + break; case GL_ADD: - switch (format) { - case GL_RGB: - case GL_LUMINANCE: - color_combine = i810_color_combine[unit][I810_ADD]; - alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; + alpha_combine = MA_OP_ADD; + break; + case GL_ADD_SIGNED: + alpha_combine = MA_OP_ADD_SIGNED; + break; + case GL_SUBTRACT: + alpha_combine = MA_OP_SUBTRACT; + break; + case GL_INTERPOLATE: + if ( (alpha_arg[2] & MA_ARG_INVERT) != 0 ) { + unsigned temp = alpha_arg[0]; + + alpha_arg[0] = alpha_arg[1]; + alpha_arg[1] = temp; + alpha_arg[2] &= ~MA_ARG_INVERT; + } + + switch (alpha_arg[2]) { + case MA_ARG_ONE: + alpha_combine = MA_OP_ARG1; + alpha_arg[1] = MA_ARG_ITERATED_ALPHA; + break; + + case MA_ARG_ALPHA_FACTOR: + alpha_combine = MA_OP_LIN_BLEND_ALPHA_FACTOR; break; - case GL_RGBA: - case GL_LUMINANCE_ALPHA: - color_combine = i810_color_combine[unit][I810_ADD]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + + case MA_ARG_ITERATED_ALPHA: + alpha_combine = MA_OP_LIN_BLEND_ITER_ALPHA; break; - case GL_ALPHA: - color_combine = i810_color_combine[unit][I810_PASSTHRU]; - alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; + + case MA_ARG_TEX0_ALPHA: + alpha_combine = MA_OP_LIN_BLEND_TEX0_ALPHA; break; - case GL_INTENSITY: - color_combine = i810_color_combine[unit][I810_ADD]; - alpha_combine = i810_alpha_combine[unit][I810_ADD]; + + case MA_ARG_TEX1_ALPHA: + alpha_combine = MA_OP_LIN_BLEND_TEX1_ALPHA; break; - case GL_COLOR_INDEX: + default: - return; + return GL_FALSE; } break; default: - return; + return GL_FALSE; } - if (alpha_combine != imesa->Setup[I810_CTXREG_MA0 + unit] || - color_combine != imesa->Setup[I810_CTXREG_MC0 + unit]) - { - I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); - imesa->Setup[I810_CTXREG_MA0 + unit] = alpha_combine; - imesa->Setup[I810_CTXREG_MC0 + unit] = color_combine; - } -} + color_combine |= GFX_OP_MAP_COLOR_STAGES | (*color_stage << MC_STAGE_SHIFT) + | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (color_arg[0] << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (color_arg[1] << MC_ARG2_SHIFT) + | MC_UPDATE_OP; + + alpha_combine |= GFX_OP_MAP_ALPHA_STAGES | (*alpha_stage << MA_STAGE_SHIFT) + | MA_UPDATE_ARG1 | (alpha_arg[0] << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (alpha_arg[1] << MA_ARG2_SHIFT) + | MA_UPDATE_OP; + set_color_stage( color_combine, *color_stage, imesa ); + set_alpha_stage( alpha_combine, *alpha_stage, imesa ); + (*color_stage)++; + (*alpha_stage)++; -static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit ) + /* Step 3: + * Apply the scale factor. + */ + /* The only operation where the i810 directly supports adding a post- + * scale factor is modulate. For all the other modes the post-scale is + * emulated by inserting and extra modulate stage. For the modulate + * case, the scaling is handled above when color_combine / alpha_combine + * are initially set. + */ + + if ( RGBshift != 0 ) { + const unsigned color_scale = GFX_OP_MAP_COLOR_STAGES + | (*color_stage << MC_STAGE_SHIFT) + | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT) + | MC_UPDATE_OP | (MC_OP_MODULATE + RGBshift); + + if ( *color_stage >= 3 ) { + return GL_FALSE; + } + + set_color_stage( color_scale, *color_stage, imesa ); + (*color_stage)++; + } + + + if ( Ashift != 0 ) { + const unsigned alpha_scale = GFX_OP_MAP_ALPHA_STAGES + | (*alpha_stage << MA_STAGE_SHIFT) + | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (MA_ARG_ONE << MA_ARG2_SHIFT) + | MA_UPDATE_OP | (MA_OP_MODULATE + Ashift); + + if ( *alpha_stage >= 3 ) { + return GL_FALSE; + } + + set_alpha_stage( alpha_scale, *alpha_stage, imesa ); + (*alpha_stage)++; + } + + return GL_TRUE; +} + + +/** + * Update hardware state for a texture unit. + * + * \todo + * 1D textures should be supported! Just use a 2D texture with the second + * texture coordinate value fixed at 0.0. + */ +static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit, + int * next_color_stage, int * next_alpha_stage ) { i810ContextPtr imesa = I810_CONTEXT(ctx); struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - if (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) - { - struct gl_texture_object *tObj = texUnit->_Current; - i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData; + if ( (texUnit->_ReallyEnabled == TEXTURE_2D_BIT) + || (texUnit->_ReallyEnabled == 0) ) { + if (texUnit->_ReallyEnabled != 0) { + struct gl_texture_object *tObj = texUnit->_Current; + i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData; - /* Upload teximages (not pipelined) - */ - if (t->base.dirty_images[0]) { - I810_FIREVERTICES(imesa); - i810SetTexImages( imesa, tObj ); - if (!t->base.memBlock) { + if (tObj->Image[0][tObj->BaseLevel]->Border > 0) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); return; } - } - if (tObj->Image[0][tObj->BaseLevel]->Border > 0) { - FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); - return; - } - /* Update state if this is a different texture object to last - * time. - */ - if (imesa->CurrentTexObj[unit] != t) { - I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<CurrentTexObj[unit] = t; - t->base.bound |= (1U << unit); - - driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked */ + /* Upload teximages (not pipelined) + */ + if (t->base.dirty_images[0]) { + I810_FIREVERTICES(imesa); + i810SetTexImages( imesa, tObj ); + if (!t->base.memBlock) { + FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); + return; + } + } - } + + /* Update state if this is a different texture object to last + * time. + */ + if (imesa->CurrentTexObj[unit] != t) { + I810_STATECHANGE(imesa, (I810_UPLOAD_TEX0<CurrentTexObj[unit] = t; + t->base.bound |= (1U << unit); + + /* XXX: should be locked */ + driUpdateTextureLRU( (driTextureObject *) t ); + } - /* Update texture environment if texture object image format or - * texture environment state has changed. - */ - if (tObj->Image[0][tObj->BaseLevel]->Format != imesa->TexEnvImageFmt[unit]) { + /* Update texture environment if texture object image format or + * texture environment state has changed. + */ + imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->Format; - i810UpdateTexEnv( ctx, unit ); + } + else { + imesa->CurrentTexObj[unit] = 0; + imesa->TexEnvImageFmt[unit] = 0; + imesa->dirty &= ~(I810_UPLOAD_TEX0<_ReallyEnabled) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); } - else /*if (imesa->CurrentTexObj[unit])*/ { - imesa->CurrentTexObj[unit] = 0; - imesa->TexEnvImageFmt[unit] = 0; - imesa->dirty &= ~(I810_UPLOAD_TEX0<Setup[I810_CTXREG_MA0 + unit] = - i810_alpha_combine[unit][I810_DISABLE]; - imesa->Setup[I810_CTXREG_MC0 + unit] = - i810_color_combine[unit][I810_DISABLE]; - I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); - } + + return; } void i810UpdateTextureState( GLcontext *ctx ) { + static const unsigned color_pass[3] = { + GFX_OP_MAP_COLOR_STAGES | MC_STAGE_0 | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (MC_ARG_ITERATED_COLOR << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT) + | MC_UPDATE_OP | MC_OP_ARG1, + GFX_OP_MAP_COLOR_STAGES | MC_STAGE_1 | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT) + | MC_UPDATE_OP | MC_OP_ARG1, + GFX_OP_MAP_COLOR_STAGES | MC_STAGE_2 | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (MC_ARG_CURRENT_COLOR << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT) + | MC_UPDATE_OP | MC_OP_ARG1 + }; + static const unsigned alpha_pass[3] = { + GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_0 + | MA_UPDATE_ARG1 | (MA_ARG_ITERATED_ALPHA << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (MA_ARG_ITERATED_ALPHA << MA_ARG2_SHIFT) + | MA_UPDATE_OP | MA_OP_ARG1, + GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_1 + | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT) + | MA_UPDATE_OP | MA_OP_ARG1, + GFX_OP_MAP_ALPHA_STAGES | MA_STAGE_2 + | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT) + | MA_UPDATE_OP | MA_OP_ARG1 + }; i810ContextPtr imesa = I810_CONTEXT(ctx); + int next_color_stage = 0; + int next_alpha_stage = 0; + + /* fprintf(stderr, "%s\n", __FUNCTION__); */ FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_FALSE ); - i810UpdateTexUnit( ctx, 0 ); - i810UpdateTexUnit( ctx, 1 ); -} + i810UpdateTexUnit( ctx, 0, & next_color_stage, & next_alpha_stage ); + i810UpdateTexUnit( ctx, 1, & next_color_stage, & next_alpha_stage ); + /* There needs to be at least one combine stage emitted that just moves + * the incoming primary color to the current color register. In addition, + * there number be the same number of color and alpha stages emitted. + * Finally, if there are less than 3 combine stages, a MC_OP_DISABLE stage + * must be emitted. + */ + + while ( (next_color_stage == 0) || + (next_color_stage < next_alpha_stage) ) { + set_color_stage( color_pass[ next_color_stage ], next_color_stage, + imesa ); + next_color_stage++; + } + assert( next_color_stage <= 3 ); + + while ( next_alpha_stage < next_color_stage ) { + set_alpha_stage( alpha_pass[ next_alpha_stage ], next_alpha_stage, + imesa ); + next_alpha_stage++; + } + + assert( next_alpha_stage <= 3 ); + assert( next_color_stage == next_alpha_stage ); + + if ( next_color_stage < 3 ) { + const unsigned color = GFX_OP_MAP_COLOR_STAGES + | (next_color_stage << MC_STAGE_SHIFT) + | MC_UPDATE_DEST | MC_DEST_CURRENT + | MC_UPDATE_ARG1 | (MC_ARG_ONE << MC_ARG1_SHIFT) + | MC_UPDATE_ARG2 | (MC_ARG_ONE << MC_ARG2_SHIFT) + | MC_UPDATE_OP | (MC_OP_DISABLE); + + const unsigned alpha = GFX_OP_MAP_ALPHA_STAGES + | (next_color_stage << MC_STAGE_SHIFT) + | MA_UPDATE_ARG1 | (MA_ARG_CURRENT_ALPHA << MA_ARG1_SHIFT) + | MA_UPDATE_ARG2 | (MA_ARG_CURRENT_ALPHA << MA_ARG2_SHIFT) + | MA_UPDATE_OP | (MA_OP_ARG1); + + set_color_stage( color, next_color_stage, imesa ); + set_alpha_stage( alpha, next_alpha_stage, imesa ); + } +}