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
1 changed files with 22 additions and 30 deletions

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);
const char *tevScaleTable[] =
const char *tevScaleTableLeft[] =
{
"", // SCALE_1
" << 1", // SCALE_2
" << 2", // SCALE_4
"", // DIVIDE_2
};
const char *tevScaleTableRight[] =
{
"", // SCALE_1
"", // SCALE_2
"", // SCALE_4
" >> 1", // DIVIDE_2
};
const char *tevLerpBias[] = // indexed by 2*op+(shift==3)
{
"",
" + 128",
"",
" + 127",
};
const char *tevBiasTable[] =
{
"", // ZERO,
"+ 128", // ADDHALF,
"- 128", // SUBHALF,
" + 128", // ADDHALF,
" - 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
if (cc.bias != TevBias_COMPARE) // if not compare
{
//normal color combiner goes here
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]);
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]);
}
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
{
//normal alpha combiner goes here
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]);
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]);
}
else
{