summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
diff options
context:
space:
mode:
authorNeoBrainX <NeoBrainX@gmail.com>2013-01-08 16:40:15 +0100
committerNeoBrainX <NeoBrainX@gmail.com>2013-01-08 18:16:48 +0100
commitb06f30f8452af075f5929e37f168e54bfd37083a (patch)
treefde3eefba7d669b4326788776cc859f81d7c9f22 /Source/Core/VideoCommon/Src/PixelShaderGen.cpp
parent876eee5e601915dd361a16899754d35b43cae80c (diff)
Remove the per pixel depth option.
Depth calculations are always done in the pixel shader now. Due to the unpredictability of our zcomploc hacks this commit probably changes the behavior of some games which use zcomploc.
Diffstat (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp')
-rw-r--r--Source/Core/VideoCommon/Src/PixelShaderGen.cpp173
1 files changed, 69 insertions, 104 deletions
diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
index 36aa4e930d..dbc65669ff 100644
--- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
+++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp
@@ -27,7 +27,12 @@
#include "VideoConfig.h"
#include "NativeVertexFormat.h"
-static int AlphaPreTest();
+
+#define ALPHATEST_PASS 2
+#define ALPHATEST_FAIL 1
+#define ALPHATEST_UNDETERMINED 0
+
+static unsigned int AlphaPreTest();
static void StageHash(int stage, u32* out)
{
@@ -109,29 +114,17 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
uid->values[0] |= bpmem.genMode.numtexgens << 4; // 4
uid->values[0] |= dstAlphaMode << 8; // 2
- bool DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth;
-
- uid->values[0] |= DepthTextureEnable << 10; // 1
-
bool enablePL = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting;
- uid->values[0] |= enablePL << 11; // 1
+ uid->values[0] |= enablePL << 10; // 1
- if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 12; // 4
- u32 alphaPreTest = AlphaPreTest()+1;
+ if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4
- uid->values[0] |= alphaPreTest << 16; // 2
-
- if (alphaPreTest == 1 || (alphaPreTest && !DepthTextureEnable && dstAlphaMode == DSTALPHA_ALPHA_PASS))
- {
- // Courtesy of PreAlphaTest, we're done already ;)
- // NOTE: The comment header of generated shaders depends on the value of bpmem.genmode.numindstages.. shouldnt really bother about that though.
- uid->num_values = 1;
- return;
- }
+ u32 alphaPreTest = AlphaPreTest();
+ uid->values[0] |= alphaPreTest << 15; // 2
// numtexgens should be <= 8
for (unsigned int i = 0; i < bpmem.genMode.numtexgens; ++i)
- uid->values[0] |= xfregs.texMtxInfo[i].projection << (18+i); // 1
+ uid->values[0] |= xfregs.texMtxInfo[i].projection << (17+i); // 1
uid->values[1] = bpmem.genMode.numindstages; // 3
u32 indirectStagesUsed = 0;
@@ -164,18 +157,17 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo
ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3
ptr[0] |= bpmem.alphaFunc.logic << 6; // 2
- if (alphaPreTest == 0 || alphaPreTest == 2)
+ if (alphaPreTest != ALPHATEST_FAIL)
{
ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3
- if (DepthTextureEnable)
- {
- ptr[0] |= bpmem.ztex2.op << 11; // 2
- ptr[0] |= bpmem.zcontrol.early_ztest << 13; // 1
- ptr[0] |= bpmem.zmode.testenable << 14; // 1
- ptr[0] |= bpmem.zmode.updateenable << 15; // 1
- }
+ ptr[0] |= bpmem.ztex2.op << 11; // 2
+// ptr[0] |= bpmem.zcontrol.early_ztest << 13; // 1
+ ptr[0] |= bpmem.zmode.testenable << 14; // 1
}
+ ptr[0] |= bpmem.zcontrol.early_ztest << 13; // 1
+ ptr[0] |= bpmem.zmode.updateenable << 15; // 1
+
if (dstAlphaMode != DSTALPHA_ALPHA_PASS)
{
if (bpmem.fog.c_proj_fsel.fsel != 0)
@@ -204,9 +196,8 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u
*ptr++ = bpmem.ztex2.hex; // 2
*ptr++ = bpmem.zcontrol.hex; // 3
*ptr++ = bpmem.zmode.hex; // 4
- *ptr++ = g_ActiveConfig.bEnablePerPixelDepth; // 5
- *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 6
- *ptr++ = xfregs.numTexGen.hex; // 7
+ *ptr++ = g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting; // 5
+ *ptr++ = xfregs.numTexGen.hex; // 6
if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting)
{
@@ -218,28 +209,28 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u
}
for (unsigned int i = 0; i < 8; ++i)
- *ptr++ = xfregs.texMtxInfo[i].hex; // 8-15
+ *ptr++ = xfregs.texMtxInfo[i].hex; // 7-14
for (unsigned int i = 0; i < 16; ++i)
- *ptr++ = bpmem.tevind[i].hex; // 16-31
+ *ptr++ = bpmem.tevind[i].hex; // 15-30
- *ptr++ = bpmem.tevindref.hex; // 32
+ *ptr++ = bpmem.tevindref.hex; // 31
for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times
{
- *ptr++ = bpmem.combiners[i].colorC.hex; // 33+5*i
- *ptr++ = bpmem.combiners[i].alphaC.hex; // 34+5*i
- *ptr++ = bpmem.tevind[i].hex; // 35+5*i
- *ptr++ = bpmem.tevksel[i/2].hex; // 36+5*i
- *ptr++ = bpmem.tevorders[i/2].hex; // 37+5*i
+ *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i
+ *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i
+ *ptr++ = bpmem.tevind[i].hex; // 34+5*i
+ *ptr++ = bpmem.tevksel[i/2].hex; // 35+5*i
+ *ptr++ = bpmem.tevorders[i/2].hex; // 36+5*i
}
- ptr = &uid->values[113];
+ ptr = &uid->values[112];
- *ptr++ = bpmem.alphaFunc.hex; // 113
+ *ptr++ = bpmem.alphaFunc.hex; // 112
- *ptr++ = bpmem.fog.c_proj_fsel.hex; // 114
- *ptr++ = bpmem.fogRange.Base.hex; // 115
+ *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113
+ *ptr++ = bpmem.fogRange.Base.hex; // 114
_assert_((ptr - uid->values) == uid->GetNumValues());
}
@@ -481,7 +472,6 @@ static const char *tevIndFmtScale[] = {"255.0f", "31.0f", "15.0f", "7.0f" };
static char swapModeTable[4][5];
static char text[16384];
-static bool DepthTextureEnable;
struct RegisterState
{
@@ -528,7 +518,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt;
}
}
- DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth ;
// Declare samplers
if(ApiType != API_D3D11)
@@ -584,14 +573,14 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
{
WRITE(p, " out float4 ocol0 : COLOR0,%s%s\n in float4 rawpos : %s,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : COLOR1," : "",
- DepthTextureEnable ? "\n out float depth : DEPTH," : "",
+ "\n out float depth : DEPTH,",
ApiType & API_OPENGL ? "WPOS" : ApiType & API_D3D9_SM20 ? "POSITION" : "VPOS");
}
else
{
WRITE(p, " out float4 ocol0 : SV_Target0,%s%s\n in float4 rawpos : SV_Position,\n",
dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND ? "\n out float4 ocol1 : SV_Target1," : "",
- DepthTextureEnable ? "\n out float depth : SV_Depth," : "");
+ "\n out float depth : SV_Depth,");
}
WRITE(p, " in float4 colors_0 : COLOR0,\n");
@@ -622,32 +611,6 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
}
WRITE(p, " ) {\n");
- int Pretest = AlphaPreTest();
- if(Pretest >= 0 && !DepthTextureEnable)
- {
- if (!Pretest)
- {
- // alpha test will always fail, so restart the shader and just make it an empty function
- WRITE(p, "ocol0 = 0;\n");
- if(DepthTextureEnable)
- WRITE(p, "depth = 1.f;\n");
- if(dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
- WRITE(p, "ocol1 = 0;\n");
- WRITE(p, "discard;\n");
- if(ApiType != API_D3D11)
- WRITE(p, "return;\n");
- }
- else if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
- {
- WRITE(p, " ocol0 = " I_ALPHA"[0].aaaa;\n");
- }
- if(!Pretest || dstAlphaMode == DSTALPHA_ALPHA_PASS)
- {
- WRITE(p, "}\n");
- return text;
- }
- }
-
WRITE(p, " float4 c0 = " I_COLORS"[1], c1 = " I_COLORS"[2], c2 = " I_COLORS"[3], prev = float4(0.0f, 0.0f, 0.0f, 0.0f), textemp = float4(0.0f, 0.0f, 0.0f, 0.0f), rastemp = float4(0.0f, 0.0f, 0.0f, 0.0f), konsttemp = float4(0.0f, 0.0f, 0.0f, 0.0f);\n"
" float3 comp16 = float3(1.0f, 255.0f, 0.0f), comp24 = float3(1.0f, 255.0f, 255.0f*255.0f);\n"
" float4 alphabump=float4(0.0f,0.0f,0.0f,0.0f);\n"
@@ -755,33 +718,27 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType
if(RegisterStates[0].AlphaNeedOverflowControl || RegisterStates[0].ColorNeedOverflowControl)
WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n");
- if(Pretest == -1)
- {
+ // TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state
+ int Pretest = AlphaPreTest();
+ if (Pretest == ALPHATEST_UNDETERMINED)
WriteAlphaTest(p, ApiType, dstAlphaMode);
- }
- if((bpmem.fog.c_proj_fsel.fsel != 0) || DepthTextureEnable)
- {
- // the screen space depth value = far z + (clip z / clip w) * z range
- WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n");
- }
+ // the screen space depth value = far z + (clip z / clip w) * z range
+ WRITE(p, "float zCoord = " I_ZBIAS"[1].x + (clipPos.z / clipPos.w) * " I_ZBIAS"[1].y;\n");
- if (DepthTextureEnable)
+ // Note: depth textures are disabled if early depth test is enabled
+ if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable)
{
// use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format...
- // Note: depth textures are disabled if early depth test is enabled
- if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable)
- {
- WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n",
- (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : "");
+ WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w %s;\n",
+ (bpmem.ztex2.op == ZTEXTURE_ADD) ? "+ zCoord" : "");
- // scale to make result from frac correct
- WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n");
- WRITE(p, "zCoord = frac(zCoord);\n");
- WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n");
- }
- WRITE(p, "depth = zCoord;\n");
+ // scale to make result from frac correct
+ WRITE(p, "zCoord = zCoord * (16777215.0f/16777216.0f);\n");
+ WRITE(p, "zCoord = frac(zCoord);\n");
+ WRITE(p, "zCoord = zCoord * (16777216.0f/16777215.0f);\n");
}
+ WRITE(p, "depth = zCoord;\n");
if (dstAlphaMode == DSTALPHA_ALPHA_PASS)
WRITE(p, " ocol0 = float4(prev.rgb, " I_ALPHA"[0].a);\n");
@@ -1191,37 +1148,46 @@ static const char *tevAlphaFunclogicTable[] =
" != ", // xor
" == " // xnor
};
-static int AlphaPreTest()
+
+static unsigned int AlphaPreTest()
{
u32 op = bpmem.alphaFunc.logic;
- u32 comp[2] = {bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1};
+ u32 comp[2] = { bpmem.alphaFunc.comp0, bpmem.alphaFunc.comp1 };
// First kill all the simple cases
switch(op)
{
case 0: // AND
- if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) return true;
- if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER) return false;
+ if (comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS)
+ return ALPHATEST_PASS;
+ if (comp[0] == ALPHACMP_NEVER || comp[1] == ALPHACMP_NEVER)
+ return ALPHATEST_FAIL;
break;
+
case 1: // OR
- if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS) return true;
- if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)return false;
+ if (comp[0] == ALPHACMP_ALWAYS || comp[1] == ALPHACMP_ALWAYS)
+ return ALPHATEST_PASS;
+ if (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)
+ return ALPHATEST_FAIL;
break;
+
case 2: // XOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
- return true;
+ return ALPHATEST_PASS;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
- return false;
+ return ALPHATEST_FAIL;
break;
+
case 3: // XNOR
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_NEVER) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_ALWAYS))
- return false;
+ return ALPHATEST_FAIL;
if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER))
- return true;
+ return ALPHATEST_PASS;
break;
+
default: PanicAlert("bad logic for alpha test? %08x", op);
}
- return -1;
+ return ALPHATEST_UNDETERMINED;
}
@@ -1248,8 +1214,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode
WRITE(p, "ocol0 = 0;\n");
if (dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND)
WRITE(p, "ocol1 = 0;\n");
- if (DepthTextureEnable)
- WRITE(p, "depth = 1.f;\n");
+ WRITE(p, "depth = 1.f;\n");
// HAXX: zcomploc is a way to control whether depth test is done before
// or after texturing and alpha test. PC GPU does depth test before texturing ONLY if depth value is