PixelShaderGen: Implement tev combiner lerping in a faster way which also reproduces hardware behavior perfectly.

The new behavior has been verified to be correct by hardware tests. This is an improvement over the old code, which was just a guess.
This commit is contained in:
Tony Wasserka
2014-03-20 20:49:09 +01:00
parent fdad95c055
commit 4f82d6f7af

View File

@ -759,19 +759,35 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
out.SetConstantsUsed(C_COLORS+ac.dest, C_COLORS+ac.dest); out.SetConstantsUsed(C_COLORS+ac.dest, C_COLORS+ac.dest);
const char *tevScaleTable[] = const char *tevScaleTableLeft[] =
{ {
"", // SCALE_1 "", // SCALE_1
" << 1", // SCALE_2 " << 1", // SCALE_2
" << 2", // SCALE_4 " << 2", // SCALE_4
"", // DIVIDE_2
};
const char *tevScaleTableRight[] =
{
"", // SCALE_1
"", // SCALE_2
"", // SCALE_4
" >> 1", // DIVIDE_2 " >> 1", // DIVIDE_2
}; };
const char *tevLerpBias[] = // indexed by 2*op+(shift==3)
{
"",
" + 128",
"",
" + 127",
};
const char *tevBiasTable[] = const char *tevBiasTable[] =
{ {
"", // ZERO, "", // ZERO,
"+ 128", // ADDHALF, " + 128", // ADDHALF,
"- 128", // SUBHALF, " - 128", // SUBHALF,
"", "",
}; };
@ -791,19 +807,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
// combine the color channel // combine the color channel
if (cc.bias != TevBias_COMPARE) // if not compare if (cc.bias != TevBias_COMPARE) // if not compare
{ {
//normal color combiner goes here out.Write("(((tevin_d.rgb%s)%s) %s ((((tevin_a.rgb*256 + (tevin_b.rgb-tevin_a.rgb)*(tevin_c.rgb+(tevin_c.rgb>>7)))%s)%s)>>8))%s", tevBiasTable[cc.bias], tevScaleTableLeft[cc.shift], tevOpTable[cc.op], tevScaleTableLeft[cc.shift], tevLerpBias[2*cc.op+(cc.shift==3)], tevScaleTableRight[cc.shift]);
if (cc.shift > TEVSCALE_1)
out.Write("(");
if (!(cc.d == TEVCOLORARG_ZERO && cc.op == TEVOP_ADD))
out.Write("tevin_d.rgb %s ", tevOpTable[cc.op]);
out.Write("(tevin_a.rgb * (int3(255,255,255) - tevin_c.rgb) + tevin_b.rgb * tevin_c.rgb) / 255");
out.Write(" %s", tevBiasTable[cc.bias]);
if (cc.shift > TEVSCALE_1)
out.Write(")%s", tevScaleTable[cc.shift]);
} }
else else
{ {
@ -834,19 +838,7 @@ static inline void WriteStage(T& out, pixel_shader_uid_data& uid_data, int n, AP
if (ac.bias != TevBias_COMPARE) // if not compare if (ac.bias != TevBias_COMPARE) // if not compare
{ {
//normal alpha combiner goes here out.Write("(((tevin_d.a%s)%s) %s ((((tevin_a.a*256 + (tevin_b.a-tevin_a.a)*(tevin_c.a+(tevin_c.a>>7)))%s)%s)>>8))%s", tevBiasTable[ac.bias], tevScaleTableLeft[ac.shift], tevOpTable[ac.op], tevScaleTableLeft[ac.shift], tevLerpBias[2*ac.op+(ac.shift==3)], tevScaleTableRight[ac.shift]);
if (ac.shift > 0)
out.Write("(");
if (!(ac.d == TEVALPHAARG_ZERO && ac.op == TEVOP_ADD))
out.Write("tevin_d.a %s ", tevOpTable[ac.op]);
out.Write("(tevin_a.a * (255 - tevin_c.a) + tevin_b.a * tevin_c.a) / 255");
out.Write(" %s",tevBiasTable[ac.bias]);
if (ac.shift>0)
out.Write(")%s", tevScaleTable[ac.shift]);
} }
else else
{ {