📄 i810texstate.c
字号:
* 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 (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; case (MC_ARG_TEX1_COLOR | MC_ARG_REPLICATE_ALPHA): color_combine = MC_OP_LIN_BLEND_TEX1_ALPHA; break; 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: 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]; 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 MA_ARG_ITERATED_ALPHA: alpha_combine = MA_OP_LIN_BLEND_ITER_ALPHA; break; case MA_ARG_TEX0_ALPHA: alpha_combine = MA_OP_LIN_BLEND_TEX0_ALPHA; break; case MA_ARG_TEX1_ALPHA: alpha_combine = MA_OP_LIN_BLEND_TEX1_ALPHA; break; default: return GL_FALSE; } break; default: return GL_FALSE; } 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); 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) || (texUnit->_ReallyEnabled == 0) ) { if (texUnit->_ReallyEnabled != 0) { struct gl_texture_object *tObj = texUnit->_Current; i810TextureObjectPtr t = (i810TextureObjectPtr)tObj->DriverData; if (tObj->Image[0][tObj->BaseLevel]->Border > 0) { FALLBACK( imesa, I810_FALLBACK_TEXTURE, GL_TRUE ); return; } /* 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. */ imesa->TexEnvImageFmt[unit] = tObj->Image[0][tObj->BaseLevel]->_BaseFormat; } 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 ); } 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, & 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 ); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -