diff options
| author | Ian Romanick <idr@us.ibm.com> | 2005-08-29 15:43:02 +0000 | 
|---|---|---|
| committer | Ian Romanick <idr@us.ibm.com> | 2005-08-29 15:43:02 +0000 | 
| commit | f0d0e5099417796b629ad76e4e2fc19baa31c38d (patch) | |
| tree | 8b097dec9c66c1e783def8dd398bc06fa783f9fc /src | |
| parent | d9089ab96ecfbc9fbd8f6c772b08d2217dbeacaf (diff) | |
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.
Diffstat (limited to 'src')
| -rw-r--r-- | src/mesa/drivers/dri/i810/i810_3d_reg.h | 151 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i810/i810context.c | 5 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i810/i810state.c | 60 | ||||
| -rw-r--r-- | src/mesa/drivers/dri/i810/i810texstate.c | 995 | 
4 files changed, 578 insertions, 633 deletions
diff --git a/src/mesa/drivers/dri/i810/i810_3d_reg.h b/src/mesa/drivers/dri/i810/i810_3d_reg.h index dade1a826c..7cc59d5c86 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 47c41c5db2..fd80e7675c 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 62dc819b32..c4662e8958 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 10a15f961f..6b6d1d727f 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] = +static void set_color_stage( unsigned color, int stage, +			      i810ContextPtr imesa )  { -   /* 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 ), +   if ( color != imesa->Setup[I810_CTXREG_MC0 + stage] ) { +      I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); +      imesa->Setup[I810_CTXREG_MC0 + stage] = color; +   } +} -      /* 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 ), +static void set_alpha_stage( unsigned alpha, int stage, +				    i810ContextPtr imesa ) +{ +   if ( alpha != imesa->Setup[I810_CTXREG_MA0 + stage] ) { +      I810_STATECHANGE( imesa, I810_UPLOAD_CTX ); +      imesa->Setup[I810_CTXREG_MA0 + stage] = alpha; +   } +} -      /* 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 ), +static const unsigned operand_modifiers[] = { +   0,                       MC_ARG_INVERT, +   MC_ARG_REPLICATE_ALPHA,  MC_ARG_INVERT | MC_ARG_REPLICATE_ALPHA +}; -      /* 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 ), +/** + * 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]; +   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; -      /* 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 ), +   if ( !texUnit->_ReallyEnabled ) { +      return GL_TRUE; +   } -      /* 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 ), +   if ((*color_stage >= 3) || (*alpha_stage >= 3)) { +      return GL_FALSE; +   } -      /* 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 ), +   /* Step 1: +    * Extract the color and alpha combine function arguments. +    */ -      /* 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 ), +   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; -      /* 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 ), +	 /*FALLTHROUGH*/ -      /* 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 ), -   } -}; +      case GL_ONE: +	 color_arg[i] = MC_ARG_ONE; +	 break; +      default: +	 return GL_FALSE; +      } -static GLuint i810_alpha_combine[][I810_MAX_COMBFUNC] = -{ -   /* 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 ), +      color_arg[i] |= operand_modifiers[op]; +   } -      /* 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 ), +   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_TEXTURE: +	 alpha_arg[i] = (unit == 0) +	   ? MA_ARG_TEX0_ALPHA : MA_ARG_TEX1_ALPHA; +	 break; +      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; -      /* 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 ), +	 /*FALLTHROUGH*/ -      /* 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 ), +      case GL_ONE: +	 if (i != 2) { +	    return GL_FALSE; +	 } -      /* 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 ), +	 alpha_arg[i] = MA_ARG_ONE; +	 break; +      default: +	 return GL_FALSE; +      } -      /* 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 ), +      alpha_arg[i] |= operand_modifiers[op]; +   } -      /* 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: +   /* Step 2: +    * Build up the color and alpha combine functions.      */ -   { -      /* Disable combiner stage +   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.         */ -      ( 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 ), +	  +      if ( (color_arg[2] & MC_ARG_INVERT) != 0 ) { +	 unsigned temp = color_arg[0]; -      /* 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 ), +	 color_arg[0] = color_arg[1]; +	 color_arg[1] = temp; +	 color_arg[2] &= ~MC_ARG_INVERT; +      } -      /* 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 ), +      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; -      /* 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 ), +      case (MC_ARG_COLOR_FACTOR): +	 return GL_FALSE; -      /* 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 ), +      case (MC_ARG_COLOR_FACTOR | MC_ARG_REPLICATE_ALPHA): +	 color_combine = MC_OP_LIN_BLEND_ALPHA_FACTOR; +	 break; -      /* 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 ), +      case (MC_ARG_ITERATED_COLOR): +	 return GL_FALSE; -      /* 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 ), +      case (MC_ARG_ITERATED_COLOR | MC_ARG_REPLICATE_ALPHA): +	 color_combine = MC_OP_LIN_BLEND_ITER_ALPHA; +	 break; -      /* 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 ), -   } +      case (MC_ARG_SPECULAR_COLOR): +      case (MC_ARG_SPECULAR_COLOR | MC_ARG_REPLICATE_ALPHA): +	 return GL_FALSE; -}; +      case (MC_ARG_TEX0_COLOR): +	 color_combine = MC_OP_LIN_BLEND_TEX0_COLOR; +	 break; +      case (MC_ARG_TEX0_COLOR | MC_ARG_REPLICATE_ALPHA): +	 color_combine = MC_OP_LIN_BLEND_TEX0_ALPHA; +	 break; +      case (MC_ARG_TEX1_COLOR): +	 color_combine = MC_OP_LIN_BLEND_TEX1_COLOR; +	 break; -static void i810UpdateTexEnv( GLcontext *ctx, GLuint unit ) -{ -   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_combine, alpha_combine; +      case (MC_ARG_TEX1_COLOR | MC_ARG_REPLICATE_ALPHA): +	 color_combine = MC_OP_LIN_BLEND_TEX1_ALPHA; +	 break; -   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]; +      default: +	 return GL_FALSE;        }        break; +   default: +      return GL_FALSE; +   } + +    +   switch ( texUnit->_CurrentCombine->ModeA ) { +   case GL_REPLACE: +      alpha_combine = MA_OP_ARG1; +      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]; -      } +      alpha_combine = MA_OP_MODULATE + Ashift; +      Ashift = 0; +      break; +   case GL_ADD: +      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]; -   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]; -	 break; -      case GL_RGB: -	 color_combine = i810_color_combine[unit][I810_REPLACE]; -	 alpha_combine = i810_alpha_combine[unit][I810_PASSTHRU]; -	 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]; -	 break; -      case GL_COLOR_INDEX: -      default: -	 return; +	 alpha_arg[0] = alpha_arg[1]; +	 alpha_arg[1] = temp; +	 alpha_arg[2] &= ~MA_ARG_INVERT;        } -      break; -   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]; -	 break; -      case GL_RGBA: -      case GL_LUMINANCE_ALPHA: -	 color_combine = i810_color_combine[unit][I810_BLEND]; -	 alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; +      switch (alpha_arg[2]) { +      case MA_ARG_ONE: +	 alpha_combine = MA_OP_ARG1; +	 alpha_arg[1] = MA_ARG_ITERATED_ALPHA;  	 break; -      case GL_ALPHA: -	 color_combine = i810_color_combine[unit][I810_PASSTHRU]; -	 alpha_combine = i810_alpha_combine[unit][I810_MODULATE]; -	 break; -      case GL_INTENSITY: -	 color_combine = i810_color_combine[unit][I810_BLEND]; -	 alpha_combine = i810_alpha_combine[unit][I810_BLEND]; -	 break; -      case GL_COLOR_INDEX: -      default: -	 return; -      } -      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]; +      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)++; +   /* 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); -static void i810UpdateTexUnit( GLcontext *ctx, GLuint unit ) +      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<<unit)); -	 imesa->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<<unit)); +	    imesa->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<<unit);  +      } +       +      if (!i810UpdateTexEnvCombine( ctx, unit,  +				    next_color_stage, next_alpha_stage )) { +	 FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE );        }     }     else if (texUnit->_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<<unit);  -      imesa->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 ); +   } +}  | 
