📄 r200_texstate.c
字号:
*/ switch ( texUnit->_CurrentCombine->ModeRGB ) { case GL_REPLACE: color_combine = (R200_TXC_ARG_A_ZERO | R200_TXC_ARG_B_ZERO | R200_TXC_OP_MADD); R200_COLOR_ARG( 0, C ); break; case GL_MODULATE: color_combine = (R200_TXC_ARG_C_ZERO | R200_TXC_OP_MADD); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, B ); break; case GL_ADD: color_combine = (R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B | R200_TXC_OP_MADD); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); break; case GL_ADD_SIGNED: color_combine = (R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B | R200_TXC_BIAS_ARG_C | /* new */ R200_TXC_OP_MADD); /* was ADDSIGNED */ R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); break; case GL_SUBTRACT: color_combine = (R200_TXC_ARG_B_ZERO | R200_TXC_COMP_ARG_B | R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); break; case GL_INTERPOLATE: color_combine = (R200_TXC_OP_LERP); R200_COLOR_ARG( 0, B ); R200_COLOR_ARG( 1, A ); R200_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: /* DOT3 works differently on R200 than on R100. On R100, just * setting the DOT3 mode did everything for you. On R200, the * driver has to enable the biasing and scale in the inputs to * put them in the proper [-1,1] range. This is what the 4x and * the -0.5 in the DOT3 spec do. The post-scale is then set * normally. */ color_combine = (R200_TXC_ARG_C_ZERO | R200_TXC_OP_DOT3 | R200_TXC_BIAS_ARG_A | R200_TXC_BIAS_ARG_B | R200_TXC_SCALE_ARG_A | R200_TXC_SCALE_ARG_B); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, B ); break; case GL_MODULATE_ADD_ATI: color_combine = (R200_TXC_OP_MADD); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); R200_COLOR_ARG( 2, B ); break; case GL_MODULATE_SIGNED_ADD_ATI: color_combine = (R200_TXC_BIAS_ARG_C | /* new */ R200_TXC_OP_MADD); /* was ADDSIGNED */ R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); R200_COLOR_ARG( 2, B ); break; case GL_MODULATE_SUBTRACT_ATI: color_combine = (R200_TXC_NEG_ARG_C | R200_TXC_OP_MADD); R200_COLOR_ARG( 0, A ); R200_COLOR_ARG( 1, C ); R200_COLOR_ARG( 2, B ); break; default: return GL_FALSE; } switch ( texUnit->_CurrentCombine->ModeA ) { case GL_REPLACE: alpha_combine = (R200_TXA_ARG_A_ZERO | R200_TXA_ARG_B_ZERO | R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, C ); break; case GL_MODULATE: alpha_combine = (R200_TXA_ARG_C_ZERO | R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, B ); break; case GL_ADD: alpha_combine = (R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B | R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); break; case GL_ADD_SIGNED: alpha_combine = (R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B | R200_TXA_BIAS_ARG_C | /* new */ R200_TXA_OP_MADD); /* was ADDSIGNED */ R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); break; case GL_SUBTRACT: alpha_combine = (R200_TXA_ARG_B_ZERO | R200_TXA_COMP_ARG_B | R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); break; case GL_INTERPOLATE: alpha_combine = (R200_TXA_OP_LERP); R200_ALPHA_ARG( 0, B ); R200_ALPHA_ARG( 1, A ); R200_ALPHA_ARG( 2, C ); break; case GL_MODULATE_ADD_ATI: alpha_combine = (R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); R200_ALPHA_ARG( 2, B ); break; case GL_MODULATE_SIGNED_ADD_ATI: alpha_combine = (R200_TXA_BIAS_ARG_C | /* new */ R200_TXA_OP_MADD); /* was ADDSIGNED */ R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); R200_ALPHA_ARG( 2, B ); break; case GL_MODULATE_SUBTRACT_ATI: alpha_combine = (R200_TXA_NEG_ARG_C | R200_TXA_OP_MADD); R200_ALPHA_ARG( 0, A ); R200_ALPHA_ARG( 1, C ); R200_ALPHA_ARG( 2, B ); break; default: return GL_FALSE; } if ( (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT) || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) ) { alpha_scale |= R200_TXA_DOT_ALPHA; Ashift = RGBshift; } /* Step 3: * Apply the scale factor. */ color_scale |= (RGBshift << R200_TXC_SCALE_SHIFT); alpha_scale |= (Ashift << R200_TXA_SCALE_SHIFT); /* All done! */ } if ( rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] != color_combine || rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] != alpha_combine || rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] != color_scale || rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] != alpha_scale) { R200_STATECHANGE( rmesa, pix[slot] ); rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND] = color_combine; rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND] = alpha_combine; rmesa->hw.pix[slot].cmd[PIX_PP_TXCBLEND2] = color_scale; rmesa->hw.pix[slot].cmd[PIX_PP_TXABLEND2] = alpha_scale; } return GL_TRUE;}void r200SetTexOffset(__DRIcontext * pDRICtx, GLint texname, unsigned long long offset, GLint depth, GLuint pitch){ r200ContextPtr rmesa = pDRICtx->driverPrivate; struct gl_texture_object *tObj = _mesa_lookup_texture(rmesa->glCtx, texname); r200TexObjPtr t; if (!tObj) return; t = (r200TexObjPtr) 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_le[MESA_FORMAT_ARGB8888].format; t->pp_txfilter |= tx_table_le[MESA_FORMAT_ARGB8888].filter; break; case 24: default: t->pp_txformat = tx_table_le[MESA_FORMAT_RGB888].format; t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB888].filter; break; case 16: t->pp_txformat = tx_table_le[MESA_FORMAT_RGB565].format; t->pp_txfilter |= tx_table_le[MESA_FORMAT_RGB565].filter; break; }}#define REF_COLOR 1#define REF_ALPHA 2static GLboolean r200UpdateAllTexEnv( GLcontext *ctx ){ r200ContextPtr rmesa = R200_CONTEXT(ctx); GLint i, j, currslot; GLint maxunitused = -1; GLboolean texregfree[6] = {GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE}; GLubyte stageref[7] = {0, 0, 0, 0, 0, 0, 0}; GLint nextunit[R200_MAX_TEXTURE_UNITS] = {0, 0, 0, 0, 0, 0}; GLint currentnext = -1; GLboolean ok; /* find highest used unit */ for ( j = 0; j < R200_MAX_TEXTURE_UNITS; j++) { if (ctx->Texture.Unit[j]._ReallyEnabled) { maxunitused = j; } } stageref[maxunitused + 1] = REF_COLOR | REF_ALPHA; for ( j = maxunitused; j >= 0; j-- ) { const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[j]; rmesa->state.texture.unit[j].outputreg = -1; if (stageref[j + 1]) { /* use the lowest available reg. That gets us automatically reg0 for the last stage. need this even for disabled units, as it may get referenced due to the replace optimization */ for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS; i++ ) { if (texregfree[i]) { rmesa->state.texture.unit[j].outputreg = i; break; } } if (rmesa->state.texture.unit[j].outputreg == -1) { /* no more free regs we can use. Need a fallback :-( */ return GL_FALSE; } nextunit[j] = currentnext; if (!texUnit->_ReallyEnabled) { /* the not enabled stages are referenced "indirectly", must not cut off the lower stages */ stageref[j] = REF_COLOR | REF_ALPHA; continue; } currentnext = j; const GLuint numColorArgs = texUnit->_CurrentCombine->_NumArgsRGB; const GLuint numAlphaArgs = texUnit->_CurrentCombine->_NumArgsA; const GLboolean isdot3rgba = (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA) || (texUnit->_CurrentCombine->ModeRGB == GL_DOT3_RGBA_EXT); /* check if we need the color part, special case for dot3_rgba as if only the alpha part is referenced later on it still is using the color part */ if ((stageref[j + 1] & REF_COLOR) || isdot3rgba) { for ( i = 0 ; i < numColorArgs ; i++ ) { const GLuint srcRGBi = texUnit->_CurrentCombine->SourceRGB[i]; const GLuint op = texUnit->_CurrentCombine->OperandRGB[i]; switch ( srcRGBi ) { case GL_PREVIOUS: /* op 0/1 are referencing color, op 2/3 alpha */ stageref[j] |= (op >> 1) + 1; break; case GL_TEXTURE: texregfree[j] = GL_FALSE; break; case GL_TEXTURE0: case GL_TEXTURE1: case GL_TEXTURE2: case GL_TEXTURE3: case GL_TEXTURE4: case GL_TEXTURE5: texregfree[srcRGBi - GL_TEXTURE0] = GL_FALSE; break; default: /* don't care about other sources here */ break; } } } /* alpha args are ignored for dot3_rgba */ if ((stageref[j + 1] & REF_ALPHA) && !isdot3rgba) { for ( i = 0 ; i < numAlphaArgs ; i++ ) { const GLuint srcAi = texUnit->_CurrentCombine->SourceA[i]; switch ( srcAi ) { case GL_PREVIOUS: stageref[j] |= REF_ALPHA; break; case GL_TEXTURE: texregfree[j] = GL_FALSE; break; case GL_TEXTURE0: case GL_TEXTURE1: case GL_TEXTURE2: case GL_TEXTURE3: case GL_TEXTURE4: case GL_TEXTURE5: texregfree[srcAi - GL_TEXTURE0] = GL_FALSE; break; default: /* don't care about other sources here */ break; } } } } } /* don't enable texture sampling for units if the result is not used */ for (i = 0; i < R200_MAX_TEXTURE_UNITS; i++) { if (ctx->Texture.Unit[i]._ReallyEnabled && !texregfree[i]) rmesa->state.texture.unit[i].unitneeded = ctx->Texture.Unit[i]._ReallyEnabled; else rmesa->state.texture.unit[i].unitneeded = 0; } ok = GL_TRUE; currslot = 0; rmesa->state.envneeded = 1; i = 0; while ((i <= maxunitused) && (i >= 0)) { /* only output instruction if the results are referenced */ if (ctx->Texture.Unit[i]._ReallyEnabled && stageref[i+1]) { GLuint replaceunit = i; /* try to optimize GL_REPLACE away (only one level deep though) */ if ( (ctx->Texture.Unit[i]._CurrentCombine->ModeRGB == GL_REPLACE) && (ctx->Texture.Unit[i]._CurrentCombine->ModeA == GL_REPLACE) && (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftRGB == 0) && (ctx->Texture.Unit[i]._CurrentCombine->ScaleShiftA == 0) && (nextunit[i] > 0) ) { /* yippie! can optimize it away! */ replaceunit = i; i = nextunit[i]; } /* need env instruction slot */ rmesa->state.envneeded |= 1 << currslot; ok = r200UpdateTextureEnv( ctx, i, currslot, replaceunit ); if (!ok) return GL_FALSE; currslot++; } i = i + 1; } if (currslot == 0) { /* need one stage at least */ rmesa->state.texture.unit[0].outputreg = 0; ok = r200UpdateTextureEnv( ctx, 0, 0, 0 ); } R200_STATECHANGE( rmesa, ctx ); rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_BLEND_ENABLE_MASK | R200_MULTI_PASS_ENABLE); rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= rmesa->state.envneeded << R200_TEX_BLEND_0_ENABLE_SHIFT;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -