📄 mga_texstate.c
字号:
{ /* Unit 0: */ { /* GL_REPLACE * Cv = Cf * Av = As */ (TD0_color_arg2_diffuse | TD0_color_sel_arg2 | TD0_alpha_sel_arg1), /* GL_MODULATE * Cv = Cf * Av = Af As */ (TD0_color_arg2_diffuse | TD0_color_sel_arg2 | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul), /* GL_DECAL (undefined) * Cv = Cf * Av = Af */ (TD0_color_arg2_diffuse | TD0_color_sel_arg2 | TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cf * Av = Af As */ (TD0_color_arg2_diffuse | TD0_color_sel_arg2 | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul), }, /* Unit 1: */ { /* GL_REPLACE * Cv = Cp * Av = As */ (TD0_color_arg2_prevstage | TD0_color_sel_arg2 | TD0_alpha_sel_arg1), /* GL_MODULATE * Cv = Cp * Av = Ap As */ (TD0_color_arg2_prevstage | TD0_color_sel_arg2 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul), /* GL_DECAL (undefined) * Cv = Cp * Av = Ap */ (TD0_color_arg2_prevstage | TD0_color_sel_arg2 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2), /* GL_ADD * Cv = Cp * Av = Ap As */ (TD0_color_arg2_prevstage | TD0_color_sel_arg2 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_mul), },};static GLboolean mgaUpdateTextureEnvBlend( GLcontext *ctx, int unit ){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); const int source = mmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; const struct gl_texture_object *tObj = texUnit->_Current; GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; *reg = 0; if (format == GL_ALPHA) { /* Cv = Cf */ *reg |= (TD0_color_arg2_diffuse | TD0_color_sel_arg2); /* Av = Af As */ *reg |= (TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul); return GL_TRUE; } /* C1 = Cf ( 1 - Cs ) */ *reg |= (TD0_color_arg1_inv_enable | TD0_color_arg2_diffuse | TD0_color_sel_mul); if (format == GL_RGB || format == GL_LUMINANCE) { /* A1 = Af */ *reg |= (TD0_alpha_arg2_diffuse | TD0_alpha_sel_arg2); } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) { /* A1 = Af As */ *reg |= (TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul); } else if (format == GL_INTENSITY) { /* A1 = Af ( 1 - As ) */ *reg |= (TD0_alpha_arg1_inv_enable | TD0_alpha_arg2_diffuse | TD0_alpha_sel_mul); } if (RGB_ZERO(mmesa->envcolor[source]) && (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source]))) return GL_TRUE; /* all done */ if (ctx->Texture._EnabledUnits == 0x03) return GL_FALSE; /* need both units */ mmesa->force_dualtex = GL_TRUE; reg = &mmesa->setup.tdualstage1; *reg = 0; if (RGB_ZERO(mmesa->envcolor[source])) { /* Cv = C1 */ *reg |= (TD0_color_arg2_prevstage | TD0_color_sel_arg2); } else if (RGB_ONE(mmesa->envcolor[source])) { /* Cv = C1 + Cs */ *reg |= (TD0_color_arg2_prevstage | TD0_color_add_add | TD0_color_sel_add); } else if (RGBA_EQUAL(mmesa->envcolor[source])) { /* Cv = C1 + Cc Cs */ *reg |= (TD0_color_arg2_prevstage | TD0_color_alpha_fcol | TD0_color_arg2mul_alpha2 | TD0_color_arg1add_mulout | TD0_color_add_add | TD0_color_sel_add); mmesa->setup.fcol = mmesa->envcolor[source]; } else { return GL_FALSE; } if (format != GL_INTENSITY || ALPHA_ZERO(mmesa->envcolor[source])) { /* Av = A1 */ *reg |= (TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2); } else if (ALPHA_ONE(mmesa->envcolor[source])) { /* Av = A1 + As */ *reg |= (TD0_alpha_arg2_prevstage | TD0_alpha_add_enable | TD0_alpha_sel_add); } else { return GL_FALSE; } return GL_TRUE;}static void mgaUpdateTextureEnvG400( GLcontext *ctx, GLuint unit ){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); const int source = mmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; const struct gl_texture_object *tObj = texUnit->_Current; GLuint *reg = ((GLuint *)&mmesa->setup.tdualstage0 + unit); mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; GLenum format = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; if (tObj != ctx->Texture.Unit[source].Current2D && tObj != ctx->Texture.Unit[source].CurrentRect) return; switch (ctx->Texture.Unit[source].EnvMode) { case GL_REPLACE: if (format == GL_ALPHA) { *reg = g400_alpha_combine[unit][MGA_REPLACE]; } else if (format == GL_RGB || format == GL_LUMINANCE) { *reg = g400_color_combine[unit][MGA_REPLACE]; } else { *reg = g400_color_alpha_combine[unit][MGA_REPLACE]; } break; case GL_MODULATE: if (format == GL_ALPHA) { *reg = g400_alpha_combine[unit][MGA_MODULATE]; } else if (format == GL_RGB || format == GL_LUMINANCE) { *reg = g400_color_combine[unit][MGA_MODULATE]; } else { *reg = g400_color_alpha_combine[unit][MGA_MODULATE]; } break; case GL_DECAL: if (format == GL_RGB) { *reg = g400_color_combine[unit][MGA_DECAL]; } else if (format == GL_RGBA) { *reg = g400_color_alpha_combine[unit][MGA_DECAL]; if (ctx->Texture._EnabledUnits != 0x03) { /* Linear blending mode needs dual texturing enabled */ *(reg+1) = (TD0_color_arg2_prevstage | TD0_color_sel_arg2 | TD0_alpha_arg2_prevstage | TD0_alpha_sel_arg2); mmesa->force_dualtex = GL_TRUE; } } else { /* Undefined */ *reg = g400_alpha_combine[unit][MGA_DECAL]; } break; case GL_ADD: if (format == GL_ALPHA) { *reg = g400_alpha_combine[unit][MGA_ADD]; } else if (format == GL_RGB || format == GL_LUMINANCE) { *reg = g400_color_combine[unit][MGA_ADD]; } else if (format == GL_RGBA || format == GL_LUMINANCE_ALPHA) { *reg = g400_color_alpha_combine[unit][MGA_ADD]; } else if (format == GL_INTENSITY) { /* Cv = Cf + Cs * Av = Af + As */ if (unit == 0) { *reg = (TD0_color_arg2_diffuse | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_diffuse | TD0_alpha_add_enable | TD0_alpha_sel_add); } else { *reg = (TD0_color_arg2_prevstage | TD0_color_add_add | TD0_color_sel_add | TD0_alpha_arg2_prevstage | TD0_alpha_add_enable | TD0_alpha_sel_add); } } break; case GL_BLEND: if (!mgaUpdateTextureEnvBlend(ctx, unit)) t->texenv_fallback = GL_TRUE; break; case GL_COMBINE: if (!mgaUpdateTextureEnvCombine(ctx, unit)) t->texenv_fallback = GL_TRUE; break; default: break; }}static void disable_tex( GLcontext *ctx, int unit ){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); /* Texture unit disabled */ if ( mmesa->CurrentTexObj[unit] != NULL ) { /* The old texture is no longer bound to this texture unit. * Mark it as such. */ mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit); mmesa->CurrentTexObj[unit] = NULL; } if ( unit != 0 && !mmesa->force_dualtex ) { mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; } if ( ctx->Texture._EnabledUnits == 0 ) { mmesa->setup.dwgctl &= DC_opcod_MASK; mmesa->setup.dwgctl |= DC_opcod_trap; mmesa->hw.alpha_sel = AC_alphasel_diffused; } mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit);}static GLboolean enable_tex( GLcontext *ctx, int unit ){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); const int source = mmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; const struct gl_texture_object *tObj = texUnit->_Current; mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; /* Upload teximages (not pipelined) */ if (t->base.dirty_images[0]) { FLUSH_BATCH( mmesa ); mgaSetTexImages( mmesa, tObj ); if ( t->base.memBlock == NULL ) { return GL_FALSE; } } return GL_TRUE;}static GLboolean update_tex_common( GLcontext *ctx, int unit ){ mgaContextPtr mmesa = MGA_CONTEXT(ctx); const int source = mmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; struct gl_texture_object *tObj = texUnit->_Current; mgaTextureObjectPtr t = (mgaTextureObjectPtr) tObj->DriverData; /* Fallback if there's a texture border */ if ( tObj->Image[0][tObj->BaseLevel]->Border > 0 ) { return GL_FALSE; } /* Update state if this is a different texture object to last * time. */ if ( mmesa->CurrentTexObj[unit] != t ) { if ( mmesa->CurrentTexObj[unit] != NULL ) { /* The old texture is no longer bound to this texture unit. * Mark it as such. */ mmesa->CurrentTexObj[unit]->base.bound &= ~(1UL << unit); } mmesa->CurrentTexObj[unit] = t; t->base.bound |= (1UL << unit); driUpdateTextureLRU( (driTextureObject *) t ); /* done too often */ } /* register setup */ if ( unit == 1 ) { mmesa->setup.tdualstage1 = mmesa->setup.tdualstage0; } t->texenv_fallback = GL_FALSE; /* Set this before mgaUpdateTextureEnvG400() since * GL_ARB_texture_env_crossbar may have to disable texturing. */ mmesa->setup.dwgctl &= DC_opcod_MASK; mmesa->setup.dwgctl |= DC_opcod_texture_trap; /* FIXME: The Radeon has some cached state so that it can avoid calling * FIXME: UpdateTextureEnv in some cases. Is that possible here? */ if (MGA_IS_G400(mmesa)) { /* G400: Regardless of texture env mode, we use the alpha from the * texture unit (AC_alphasel_fromtex) since it will have already * been modulated by the incoming fragment color, if needed. * We don't want (AC_alphasel_modulate) since that'll effectively * do the modulation twice. */ mmesa->hw.alpha_sel = AC_alphasel_fromtex; mgaUpdateTextureEnvG400( ctx, unit ); } else { mgaUpdateTextureEnvG200( ctx, unit ); } t->setup.texctl2 &= TMC_dualtex_MASK; if (ctx->Texture._EnabledUnits == 0x03 || mmesa->force_dualtex) { t->setup.texctl2 |= TMC_dualtex_enable; } mmesa->dirty |= MGA_UPLOAD_CONTEXT | (MGA_UPLOAD_TEX0 << unit); FALLBACK( ctx, MGA_FALLBACK_BORDER_MODE, t->border_fallback ); return !t->border_fallback && !t->texenv_fallback;}static GLboolean updateTextureUnit( GLcontext *ctx, int unit ){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); const int source = mmesa->tmu_source[unit]; const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; if ( texUnit->_ReallyEnabled == TEXTURE_2D_BIT || texUnit->_ReallyEnabled == TEXTURE_RECT_BIT ) { return(enable_tex( ctx, unit ) && update_tex_common( ctx, unit )); } else if ( texUnit->_ReallyEnabled ) { return GL_FALSE; } else { disable_tex( ctx, unit ); return GL_TRUE; }}/* The G400 is now programmed quite differently wrt texture environment. */void mgaUpdateTextureState( GLcontext *ctx ){ mgaContextPtr mmesa = MGA_CONTEXT( ctx ); GLboolean ok; unsigned i; mmesa->force_dualtex = GL_FALSE; mmesa->fcol_used = GL_FALSE; /* This works around a quirk with the MGA hardware. If only OpenGL * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used. */ mmesa->tmu_source[0] = 0; mmesa->tmu_source[1] = 1; if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) { /* only texture 1 enabled */ mmesa->tmu_source[0] = 1; mmesa->tmu_source[1] = 0; } for ( i = 0, ok = GL_TRUE ; (i < ctx->Const.MaxTextureUnits) && ok ; i++ ) { ok = updateTextureUnit( ctx, i ); } FALLBACK( ctx, MGA_FALLBACK_TEXTURE, !ok );}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -