📄 radeon_texstate.c
字号:
{ RADEON_ALPHA_ARG_A_CURRENT_ALPHA, RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A};/* GL_ZERO table - indices 0-1 * GL_ONE table - indices 1-2 */static GLuint radeon_zero_alpha[] ={ RADEON_ALPHA_ARG_A_ZERO, RADEON_ALPHA_ARG_A_ZERO | RADEON_COMP_ARG_A, RADEON_ALPHA_ARG_A_ZERO};/* Extract the arg from slot A, shift it into the correct argument slot * and set the corresponding complement bit. */#define RADEON_COLOR_ARG( n, arg ) \do { \ color_combine |= \ ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ << RADEON_COLOR_ARG_##arg##_SHIFT); \ color_combine |= \ ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ << RADEON_COMP_ARG_##arg##_SHIFT); \} while (0)#define RADEON_ALPHA_ARG( n, arg ) \do { \ alpha_combine |= \ ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ << RADEON_ALPHA_ARG_##arg##_SHIFT); \ alpha_combine |= \ ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ << RADEON_COMP_ARG_##arg##_SHIFT); \} while (0)/* ================================================================ * Texture unit state management */static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit ){ radeonContextPtr rmesa = RADEON_CONTEXT(ctx); const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; GLuint color_combine, alpha_combine; const GLuint color_combine0 = RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | RADEON_COLOR_ARG_C_CURRENT_COLOR | RADEON_BLEND_CTL_ADD | RADEON_SCALE_1X | RADEON_CLAMP_TX; const GLuint alpha_combine0 = RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO | RADEON_ALPHA_ARG_C_CURRENT_ALPHA | RADEON_BLEND_CTL_ADD | RADEON_SCALE_1X | RADEON_CLAMP_TX; /* texUnit->_Current can be NULL if and only if the texture unit is * not actually enabled. */ assert( (texUnit->_ReallyEnabled == 0) || (texUnit->_Current != NULL) ); if ( RADEON_DEBUG & DEBUG_TEXTURE ) { fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit ); } /* Set the texture environment state. Isn't this nice and clean? * The chip will automagically set the texture alpha to 0xff when * the texture format does not include an alpha component. This * reduces the amount of special-casing we have to do, alpha-only * textures being a notable exception. Doesn't work for luminance * textures realized with I8 and ALPHA_IN_MAP not set neither (on r100). */ /* Don't cache these results. */ rmesa->state.texture.unit[unit].format = 0; rmesa->state.texture.unit[unit].envMode = 0; if ( !texUnit->_ReallyEnabled ) { color_combine = color_combine0; alpha_combine = alpha_combine0; } else { GLuint color_arg[3], alpha_arg[3]; GLuint i; const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; GLuint RGBshift = texUnit->_CurrentCombine->ScaleShiftRGB; GLuint Ashift = texUnit->_CurrentCombine->ScaleShiftA; /* Step 1: * Extract the color and alpha combine function arguments. */ for ( i = 0 ; i < numColorArgs ; i++ ) { const GLint op = texUnit->_CurrentCombine->OperandRGB[i] - GL_SRC_COLOR; const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; assert(op >= 0); assert(op <= 3); switch ( srcRGBi ) { case GL_TEXTURE: if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_ALPHA) color_arg[i] = radeon_zero_color[op]; else color_arg[i] = radeon_texture_color[op][unit]; break; case GL_CONSTANT: color_arg[i] = radeon_tfactor_color[op]; break; case GL_PRIMARY_COLOR: color_arg[i] = radeon_primary_color[op]; break; case GL_PREVIOUS: color_arg[i] = radeon_previous_color[op]; break; case GL_ZERO: color_arg[i] = radeon_zero_color[op]; break; case GL_ONE: color_arg[i] = radeon_zero_color[op+1]; break; case GL_TEXTURE0: case GL_TEXTURE1: case GL_TEXTURE2: { GLuint txunit = srcRGBi - GL_TEXTURE0; if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_ALPHA) color_arg[i] = radeon_zero_color[op]; else /* implement ogl 1.4/1.5 core spec here, not specification of * GL_ARB_texture_env_crossbar (which would require disabling blending * instead of undefined results when referencing not enabled texunit) */ color_arg[i] = radeon_texture_color[op][txunit]; } break; default: return GL_FALSE; } } for ( i = 0 ; i < numAlphaArgs ; i++ ) { const GLint op = texUnit->_CurrentCombine->OperandA[i] - GL_SRC_ALPHA; const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i]; assert(op >= 0); assert(op <= 1); switch ( srcAi ) { case GL_TEXTURE: if (texUnit->_Current->Image[0][0]->_BaseFormat == GL_LUMINANCE) alpha_arg[i] = radeon_zero_alpha[op+1]; else alpha_arg[i] = radeon_texture_alpha[op][unit]; break; case GL_CONSTANT: alpha_arg[i] = radeon_tfactor_alpha[op]; break; case GL_PRIMARY_COLOR: alpha_arg[i] = radeon_primary_alpha[op]; break; case GL_PREVIOUS: alpha_arg[i] = radeon_previous_alpha[op]; break; case GL_ZERO: alpha_arg[i] = radeon_zero_alpha[op]; break; case GL_ONE: alpha_arg[i] = radeon_zero_alpha[op+1]; break; case GL_TEXTURE0: case GL_TEXTURE1: case GL_TEXTURE2: { GLuint txunit = srcAi - GL_TEXTURE0; if (ctx->Texture.Unit[txunit]._Current->Image[0][0]->_BaseFormat == GL_LUMINANCE) alpha_arg[i] = radeon_zero_alpha[op+1]; else alpha_arg[i] = radeon_texture_alpha[op][txunit]; } break; default: return GL_FALSE; } } /* Step 2: * Build up the color and alpha combine functions. */ switch ( texUnit->_CurrentCombine->ModeRGB ) { case GL_REPLACE: color_combine = (RADEON_COLOR_ARG_A_ZERO | RADEON_COLOR_ARG_B_ZERO | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, C ); break; case GL_MODULATE: color_combine = (RADEON_COLOR_ARG_C_ZERO | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, B ); break; case GL_ADD: color_combine = (RADEON_COLOR_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); break; case GL_ADD_SIGNED: color_combine = (RADEON_COLOR_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADDSIGNED | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); break; case GL_SUBTRACT: color_combine = (RADEON_COLOR_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_SUBTRACT | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); break; case GL_INTERPOLATE: color_combine = (RADEON_BLEND_CTL_BLEND | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, B ); RADEON_COLOR_ARG( 1, A ); RADEON_COLOR_ARG( 2, C ); break; case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: /* The EXT version of the DOT3 extension does not support the * scale factor, but the ARB version (and the version in OpenGL * 1.3) does. */ RGBshift = 0; /* FALLTHROUGH */ case GL_DOT3_RGB: case GL_DOT3_RGBA: /* The R100 / RV200 only support a 1X multiplier in hardware * w/the ARB version. */ if ( RGBshift != (RADEON_SCALE_1X >> RADEON_SCALE_SHIFT) ) { return GL_FALSE; } RGBshift += 2; if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { /* is it necessary to set this or will it be ignored anyway? */ Ashift = RGBshift; } color_combine = (RADEON_COLOR_ARG_C_ZERO | RADEON_BLEND_CTL_DOT3 | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, B ); break; case GL_MODULATE_ADD_ATI: color_combine = (RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); RADEON_COLOR_ARG( 2, B ); break; case GL_MODULATE_SIGNED_ADD_ATI: color_combine = (RADEON_BLEND_CTL_ADDSIGNED | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); RADEON_COLOR_ARG( 2, B ); break; case GL_MODULATE_SUBTRACT_ATI: color_combine = (RADEON_BLEND_CTL_SUBTRACT | RADEON_CLAMP_TX); RADEON_COLOR_ARG( 0, A ); RADEON_COLOR_ARG( 1, C ); RADEON_COLOR_ARG( 2, B ); break; default: return GL_FALSE; } switch ( texUnit->_CurrentCombine->ModeA ) { case GL_REPLACE: alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | RADEON_ALPHA_ARG_B_ZERO | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, C ); break; case GL_MODULATE: alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, B ); break; case GL_ADD: alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); break; case GL_ADD_SIGNED: alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_ADDSIGNED | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); break; case GL_SUBTRACT: alpha_combine = (RADEON_COLOR_ARG_B_ZERO | RADEON_COMP_ARG_B | RADEON_BLEND_CTL_SUBTRACT | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); break; case GL_INTERPOLATE: alpha_combine = (RADEON_BLEND_CTL_BLEND | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, B ); RADEON_ALPHA_ARG( 1, A ); RADEON_ALPHA_ARG( 2, C ); break; case GL_MODULATE_ADD_ATI: alpha_combine = (RADEON_BLEND_CTL_ADD | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); RADEON_ALPHA_ARG( 2, B ); break; case GL_MODULATE_SIGNED_ADD_ATI: alpha_combine = (RADEON_BLEND_CTL_ADDSIGNED | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); RADEON_ALPHA_ARG( 2, B ); break; case GL_MODULATE_SUBTRACT_ATI: alpha_combine = (RADEON_BLEND_CTL_SUBTRACT | RADEON_CLAMP_TX); RADEON_ALPHA_ARG( 0, A ); RADEON_ALPHA_ARG( 1, C ); RADEON_ALPHA_ARG( 2, B ); break; default: return GL_FALSE; } if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB_EXT) || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGB) ) { alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; } /* Step 3: * Apply the scale factor. */ color_combine |= (RGBshift << RADEON_SCALE_SHIFT); alpha_combine |= (Ashift << RADEON_SCALE_SHIFT); /* All done! */ } if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine || rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) { RADEON_STATECHANGE( rmesa, tex[unit] ); rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine; rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine; } return GL_TRUE;}void radeonSetTexOffset(__DRIcontext * pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch){ radeonContextPtr rmesa = pDRICtx->driverPrivate; struct gl_texture_object *tObj = _mesa_lookup_texture(rmesa->glCtx, texname); radeonTexObjPtr t; if (tObj == NULL) return; t = (radeonTexObjPtr) tObj->DriverData; t->image_override = GL_TRUE; if (!offset) return; t->pp_txoffset = offset; t->pp_txpitch = pitch - 32; switch (depth) { case 32: t->pp_txformat = tx_table[MESA_FORMAT_ARGB8888].format; t->pp_txfilter |= tx_table[MESA_FORMAT_ARGB8888].filter; break; case 24: default: t->pp_txformat = tx_table[MESA_FORMAT_RGB888].format; t->pp_txfilter |= tx_table[MESA_FORMAT_RGB888].filter; break; case 16: t->pp_txformat = tx_table[MESA_FORMAT_RGB565].format; t->pp_txfilter |= tx_table[MESA_FORMAT_RGB565].filter; break; }}#define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ RADEON_MIN_FILTER_MASK | \ RADEON_MAG_FILTER_MASK | \ RADEON_MAX_ANISO_MASK | \ RADEON_YUV_TO_RGB | \ RADEON_YUV_TEMPERATURE_MASK | \ RADEON_CLAMP_S_MASK | \ RADEON_CLAMP_T_MASK | \ RADEON_BORDER_MODE_D3D )#define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \ RADEON_TXFORMAT_HEIGHT_MASK | \ RADEON_TXFORMAT_FORMAT_MASK | \ RADEON_TXFORMAT_F5_WIDTH_MASK | \ RADEON_TXFORMAT_F5_HEIGHT_MASK | \ RADEON_TXFORMAT_ALPHA_IN_MAP | \ RADEON_TXFORMAT_CUBIC_MAP_ENABLE | \ RADEON_TXFORMAT_NON_POWER2)static void import_tex_obj_state( radeonContextPtr rmesa, int unit, radeonTexObjPtr texobj ){/* do not use RADEON_DB_STATE to avoid stale texture caches */ int *cmd = &rmesa->hw.tex[unit].cmd[TEX_CMD_0]; GLuint se_coord_fmt = rmesa->hw.set.cmd[SET_SE_COORDFMT]; RADEON_STATECHANGE( rmesa, tex[unit] ); cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; cmd[TEX_PP_TXFILTER] |= texobj->pp_txfilter & TEXOBJ_TXFILTER_MASK; cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK; cmd[TEX_PP_TXOFFSET] = texobj->pp_txoffset; cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -