From 4f82d6f7aff107d3cb941df111250c66aa9f5ea8 Mon Sep 17 00:00:00 2001 From: Tony Wasserka Date: Thu, 20 Mar 2014 20:49:09 +0100 Subject: [PATCH] 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. --- Source/Core/VideoCommon/PixelShaderGen.cpp | 52 +++++++++------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 961ca9f3b1..ff8b9c2f1c 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -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, + "", // ZERO, + " + 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 {