#define INPUT_B_SHIFT 7
#define INPUT_C_SHIFT 0
#define INPUT_CBias_SHIFT 14
-#define INPUT_ABias_SHIFT 3
#define CONST_ONE (HC_XTC_0 | HC_XTC_InvTOPC)
0, HC_XTA_InvTOPA
};
+static const unsigned bias_alpha_operand_modifier[2] = {
+ 0, HC_HTXnTBLAbias_Inv
+};
+
+
static const unsigned c_shift_table[3] = {
HC_HTXnTBLCshift_No, HC_HTXnTBLCshift_1, HC_HTXnTBLCshift_2
};
* KW: needs attention to the case where texunit 1 is enabled but
* texunit 0 is not.
*/
-void
+GLboolean
viaTexCombineState( viaContextPtr vmesa,
const struct gl_tex_env_combine_state * combine,
unsigned unit )
{
unsigned color_arg[3];
unsigned alpha_arg[3];
- unsigned color = 0;
- unsigned alpha = 0;
+ unsigned bias_alpha_arg[3];
+ unsigned color = HC_HTXnTBLCsat_MASK;
+ unsigned alpha = HC_HTXnTBLAsat_MASK;
unsigned bias = 0;
unsigned op = 0;
unsigned a_shift = combine->ScaleShiftA;
unsigned i;
unsigned constant_color[3];
unsigned ordered_constant_color[4];
- unsigned constant_alpha = 0;
+ unsigned constant_alpha[3];
unsigned bias_alpha = 0;
+ unsigned abc_alpha = 0;
const struct gl_texture_unit const * texUnit = & vmesa->glCtx->Texture.Unit[unit];
unsigned env_color[4];
+ /* It seems that the color clamping can be overwhelmed at the 4x
+ * scale settings, necessitating this fallback:
+ */
+ if (c_shift == 2 || a_shift == 2) {
+ return GL_FALSE;
+ }
CLAMPED_FLOAT_TO_UBYTE(env_color[0], texUnit->EnvColor[0]);
CLAMPED_FLOAT_TO_UBYTE(env_color[1], texUnit->EnvColor[1]);
(void) memset( constant_color, 0, sizeof( constant_color ) );
(void) memset( ordered_constant_color, 0, sizeof( ordered_constant_color ) );
+ (void) memset( constant_alpha, 0, sizeof( constant_alpha ) );
for ( i = 0 ; i < combine->_NumArgsRGB ; i++ ) {
const GLint op = combine->OperandRGB[i] - GL_SRC_COLOR;
}
}
- for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
- const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
-
- switch ( combine->SourceA[i] ) {
- case GL_TEXTURE:
- alpha_arg[i] = HC_XTA_Atex;
- alpha_arg[i] += alpha_operand_modifier[op];
- break;
- case GL_CONSTANT:
- alpha_arg[i] = HC_XTA_HTXnTBLRA;
- constant_alpha = (op == 0)
- ? env_color[3] : ~(env_color[3]) & 0x000000ff;
- break;
- case GL_PRIMARY_COLOR:
- alpha_arg[i] = HC_XTA_Adif;
- alpha_arg[i] += alpha_operand_modifier[op];
- break;
- case GL_PREVIOUS:
- alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
- alpha_arg[i] += alpha_operand_modifier[op];
- break;
- }
- }
-
/* On the Unichrome, all combine operations take on some form of:
*
* and mask modes are currently unused. With the exception of DOT3, all
* standard GL_COMBINE modes can be implemented simply by selecting the
* correct inputs for A, B, C, and Bias and the correct operation for op.
+ *
+ * NOTE: xBias (when read from the constant registers) is signed,
+ * and scaled to fit -255..255 in 8 bits, ie 0x1 == 2.
*/
- color = HC_HTXnTBLCsat_MASK;
- alpha = HC_HTXnTBLAsat_MASK;
-
switch( combine->ModeRGB ) {
- /* Ca = 0, Cb = 0, Cc = 0, Cbias = arg0
+ /* Ca = 1.0, Cb = arg0, Cc = 0, Cbias = 0
*/
case GL_REPLACE:
- bias |= (color_arg[0] << INPUT_CBias_SHIFT);
- ordered_constant_color[3] = constant_color[0];
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT));
+
+ ordered_constant_color[1] = constant_color[0];
break;
/* Ca = arg[0], Cb = arg[1], Cc = 0, Cbias = 0
*/
case GL_MODULATE:
- color |= (color_arg[0] << INPUT_A_SHIFT)
- | (color_arg[1] << INPUT_B_SHIFT);
+ color |= ((color_arg[0] << INPUT_A_SHIFT) |
+ (color_arg[1] << INPUT_B_SHIFT));
ordered_constant_color[0] = constant_color[0];
ordered_constant_color[1] = constant_color[1];
break;
- /* Ca = 1.0, Cb = arg[0], Cc = 0, Cbias = arg[1]
+ /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = 0
*/
case GL_ADD:
case GL_SUBTRACT:
op |= HC_HTXnTBLCop_Sub;
}
- color |= (color_arg[0] << INPUT_B_SHIFT)
- | (CONST_ONE << INPUT_A_SHIFT);
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
- bias |= (color_arg[1] << INPUT_CBias_SHIFT);
ordered_constant_color[1] = constant_color[0];
- ordered_constant_color[3] = constant_color[1];
+ ordered_constant_color[2] = constant_color[1];
break;
- /* Ca = 0, Cb = arg[0], Cc = arg[1], Cbias = 0.5
+ /* Ca = 1.0, Cb = arg[0], Cc = arg[1], Cbias = -0.5
*/
case GL_ADD_SIGNED:
- color |= (color_arg[0] << INPUT_B_SHIFT)
- | (color_arg[1] << INPUT_C_SHIFT);
+ color |= ((CONST_ONE << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
+
bias |= HC_HTXnTBLCbias_HTXnTBLRC;
- op |= HC_HTXnTBLCop_Sub;
ordered_constant_color[1] = constant_color[0];
ordered_constant_color[2] = constant_color[1];
- ordered_constant_color[3] = 0x00808080;
+ ordered_constant_color[3] = 0x00bfbfbf; /* -.5 */
break;
/* Ca = arg[2], Cb = arg[0], Cc = arg[1], Cbias = arg[1]
case GL_INTERPOLATE:
op |= HC_HTXnTBLCop_Sub;
- color |= (color_arg[2] << INPUT_A_SHIFT) |
- (color_arg[0] << INPUT_B_SHIFT) |
- (color_arg[1] << INPUT_C_SHIFT);
+ color |= ((color_arg[2] << INPUT_A_SHIFT) |
+ (color_arg[0] << INPUT_B_SHIFT) |
+ (color_arg[1] << INPUT_C_SHIFT));
+
bias |= (color_arg[1] << INPUT_CBias_SHIFT);
ordered_constant_color[0] = constant_color[2];
ordered_constant_color[1] = constant_color[0];
ordered_constant_color[2] = constant_color[1];
- ordered_constant_color[3] = constant_color[1];
+ ordered_constant_color[3] = (constant_color[1] >> 1) & 0x7f7f7f;
break;
+#if 0
/* At this point this code is completely untested. It appears that the
* Unichrome has the same limitation as the Radeon R100. The only
* supported post-scale when doing DOT3 bumpmapping is 1x.
case GL_DOT3_RGBA:
c_shift = 2;
a_shift = 2;
- color |= (color_arg[0] << INPUT_A_SHIFT) |
- (color_arg[1] << INPUT_B_SHIFT);
+ color |= ((color_arg[0] << INPUT_A_SHIFT) |
+ (color_arg[1] << INPUT_B_SHIFT));
op |= HC_HTXnTBLDOT4;
break;
+#endif
+
+ default:
+ assert(0);
+ break;
}
+
+
/* The alpha blend stage has the annoying quirk of not having a
* hard-wired 0 input, like the color stage. As a result, we have
* to program the constant register with 0 and use that as our
* 0 input.
+ *
+ * (xA * (xB op xC) + xBias) << xShift
+ *
*/
+ for ( i = 0 ; i < combine->_NumArgsA ; i++ ) {
+ const GLint op = combine->OperandA[i] - GL_SRC_ALPHA;
+
+ switch ( combine->SourceA[i] ) {
+ case GL_TEXTURE:
+ alpha_arg[i] = HC_XTA_Atex;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_Atex;
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ case GL_CONSTANT:
+ alpha_arg[i] = HC_XTA_HTXnTBLRA;
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_HTXnTBLRAbias;
+ constant_alpha[i] = (op == 0) ? env_color[3] : (~env_color[3] & 0xff);
+ break;
+ case GL_PRIMARY_COLOR:
+ alpha_arg[i] = HC_XTA_Adif;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = HC_HTXnTBLAbias_Adif;
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ case GL_PREVIOUS:
+ alpha_arg[i] = (unit == 0) ? HC_XTA_Adif : HC_XTA_Acur;
+ alpha_arg[i] += alpha_operand_modifier[op];
+ bias_alpha_arg[i] = (unit == 0) ? HC_HTXnTBLAbias_Adif : HC_HTXnTBLAbias_Acur;
+ bias_alpha_arg[i] += bias_alpha_operand_modifier[op];
+ break;
+ }
+ }
+
switch( combine->ModeA ) {
/* Aa = 0, Ab = 0, Ac = 0, Abias = arg0
*/
case GL_REPLACE:
- bias |= (alpha_arg[0] << INPUT_ABias_SHIFT);
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+ abc_alpha = 0;
- alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
- (HC_XTA_HTXnTBLRA << INPUT_B_SHIFT) |
- (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
+ bias |= bias_alpha_arg[0];
+ bias_alpha = constant_alpha[0] >> 1;
break;
/* Aa = arg[0], Ab = arg[1], Ac = 0, Abias = 0
*/
case GL_MODULATE:
- alpha |= (alpha_arg[1] << INPUT_A_SHIFT)
- | (alpha_arg[0] << INPUT_B_SHIFT)
- | (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
+ alpha |= ((alpha_arg[1] << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT));
+
+ abc_alpha = ((constant_alpha[1] << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (0 << HC_HTXnTBLRAc_SHIFT));
- bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0;
break;
- /* Aa = 0, Ab = arg[0], Ac = 0, Abias = arg[1]
+ /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = 0
*/
case GL_ADD:
case GL_SUBTRACT:
op |= HC_HTXnTBLAop_Sub;
}
- alpha |= (HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
- (alpha_arg[0] << INPUT_B_SHIFT) |
- (HC_XTA_HTXnTBLRA << INPUT_C_SHIFT);
- bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+
+ abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0;
break;
- /* Aa = 0, Ab = arg[0], Ac = arg[1], Abias = 0.5
+ /* Aa = 1.0, Ab = arg[0], Ac = arg[1], Abias = -0.5
*/
case GL_ADD_SIGNED:
- op |= HC_HTXnTBLAop_Sub;
-
- alpha |= (alpha_arg[0] << INPUT_B_SHIFT)
- | (alpha_arg[1] << INPUT_C_SHIFT);
- bias |= (HC_XTA_HTXnTBLRA << INPUT_ABias_SHIFT);
-
- bias_alpha = 0x00000080;
+ alpha |= ((HC_XTA_HTXnTBLRA << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+ abc_alpha = ((0xff << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= HC_HTXnTBLAbias_HTXnTBLRAbias;
+ bias_alpha = 0xbf;
break;
/* Aa = arg[2], Ab = arg[0], Ac = arg[1], Abias = arg[1]
case GL_INTERPOLATE:
op |= HC_HTXnTBLAop_Sub;
- alpha |= (alpha_arg[2] << INPUT_A_SHIFT) |
- (alpha_arg[0] << INPUT_B_SHIFT) |
- (alpha_arg[1] << INPUT_C_SHIFT);
- bias |= (alpha_arg[1] << INPUT_ABias_SHIFT);
+ alpha |= ((alpha_arg[2] << INPUT_A_SHIFT) |
+ (alpha_arg[0] << INPUT_B_SHIFT) |
+ (alpha_arg[1] << INPUT_C_SHIFT));
+ abc_alpha = ((constant_alpha[2] << HC_HTXnTBLRAa_SHIFT) |
+ (constant_alpha[0] << HC_HTXnTBLRAb_SHIFT) |
+ (constant_alpha[1] << HC_HTXnTBLRAc_SHIFT));
+
+ bias |= bias_alpha_arg[1];
+ bias_alpha = constant_alpha[1] >> 1;
break;
}
vmesa->regHTXnTBLCsat_0 = color;
vmesa->regHTXnTBLAsat_0 = alpha;
vmesa->regHTXnTBLCop_0 = op | bias;
- vmesa->regHTXnTBLRAa_0 = bias_alpha | (constant_alpha << 16);
+ vmesa->regHTXnTBLRAa_0 = abc_alpha;
+ vmesa->regHTXnTBLRFog_0 = bias_alpha;
vmesa->regHTXnTBLRCa_0 = ordered_constant_color[0];
vmesa->regHTXnTBLRCb_0 = ordered_constant_color[1];
vmesa->regHTXnTBLCsat_1 = color;
vmesa->regHTXnTBLAsat_1 = alpha;
vmesa->regHTXnTBLCop_1 = op | bias;
- vmesa->regHTXnTBLRAa_1 = bias_alpha | (constant_alpha << 16);
+ vmesa->regHTXnTBLRAa_1 = abc_alpha;
+ vmesa->regHTXnTBLRFog_1 = bias_alpha;
vmesa->regHTXnTBLRCa_1 = ordered_constant_color[0];
vmesa->regHTXnTBLRCb_1 = ordered_constant_color[1];
vmesa->regHTXnTBLRCc_1 = ordered_constant_color[2];
vmesa->regHTXnTBLRCbias_1 = ordered_constant_color[3];
}
+
+ return GL_TRUE;
}