From 876eee5e601915dd361a16899754d35b43cae80c Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 16:01:15 +0100 Subject: PixelShaderGen: Don't disable depth texture emulation if z writing is disabled (this is what VideoSoftware is doing). --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index cc48276253..36aa4e930d 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -109,7 +109,7 @@ 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.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth; + 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 @@ -170,7 +170,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo if (DepthTextureEnable) { ptr[0] |= bpmem.ztex2.op << 11; // 2 - ptr[0] |= bpmem.zcontrol.zcomploc << 13; // 1 + ptr[0] |= bpmem.zcontrol.early_ztest << 13; // 1 ptr[0] |= bpmem.zmode.testenable << 14; // 1 ptr[0] |= bpmem.zmode.updateenable << 15; // 1 } @@ -528,7 +528,7 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType nIndirectStagesUsed |= 1 << bpmem.tevind[i].bt; } } - DepthTextureEnable = (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) || g_ActiveConfig.bEnablePerPixelDepth ; + 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) @@ -769,12 +769,11 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType if (DepthTextureEnable) { // use the texture input of the last texture stage (textemp), hopefully this has been read and is in correct format... - if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.zcomploc && bpmem.zmode.testenable && bpmem.zmode.updateenable) + // Note: depth textures are disabled if early depth test is enabled + if (bpmem.ztex2.op != ZTEXTURE_DISABLE && !bpmem.zcontrol.early_ztest && bpmem.zmode.testenable) { - if (bpmem.ztex2.op == ZTEXTURE_ADD) - WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w + zCoord;\n"); - else - WRITE(p, "zCoord = dot(" I_ZBIAS"[0].xyzw, textemp.xyzw) + " I_ZBIAS"[1].w;\n"); + 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"); @@ -1264,7 +1263,7 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode // depth channel. // 2 - in the next pass disable depth chanel update, but proccess the color data normally // this way is the only CORRECT way to emulate perfectly the zcomplock behaviour - if (!(bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable)) + if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { WRITE(p, "discard;\n"); if (ApiType != API_D3D11) -- cgit v1.2.3 From b06f30f8452af075f5929e37f168e54bfd37083a Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 16:40:15 +0100 Subject: 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. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 173 ++++++++++--------------- 1 file changed, 69 insertions(+), 104 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') 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 -- cgit v1.2.3 From c80f6e8b84cd98120ad55a6830a68039ab6a2a48 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 16:51:01 +0100 Subject: Reword a comment about early_ztest a bit. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index dbc65669ff..e1507e8389 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -1216,18 +1216,16 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode WRITE(p, "ocol1 = 0;\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 - // not updated during shader execution. + // HAXX: zcomploc (aka early_ztest) is a way to control whether depth test is done before + // or after texturing and alpha test. PC GPUs have no way to support this + // feature properly as of 2012: depth buffer and depth test are not + // programmable and the depth test is always done after texturing. + // Most importantly, PC GPUs do not allow writing to the z buffer without + // writing a color value (unless color writing is disabled altogether). // We implement "depth test before texturing" by discarding the fragment // when the alpha test fail. This is not a correct implementation because - // even if the depth test fails the fragment could be alpha blended. - // this implemnetation is a trick to keep speed. - // the correct, but slow, way to implement a correct zComploc is : - // 1 - if zcomplock is enebled make a first pass, with color channel write disabled updating only - // depth channel. - // 2 - in the next pass disable depth chanel update, but proccess the color data normally - // this way is the only CORRECT way to emulate perfectly the zcomplock behaviour + // even if the depth test fails the fragment could be alpha blended, but + // we don't have a choice. if (!(bpmem.zcontrol.early_ztest && bpmem.zmode.updateenable)) { WRITE(p, "discard;\n"); @@ -1236,7 +1234,6 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode } WRITE(p, "}\n"); - } static const char *tevFogFuncsTable[] = -- cgit v1.2.3 From d26bcb0847ad27235020ecaf749154d388f0e162 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 17:18:45 +0100 Subject: Move alpha pretest to BPMemory.h and rename a bunch of alpha testing related stuff --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 70 ++++---------------------- 1 file changed, 11 insertions(+), 59 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index e1507e8389..b408b1bceb 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -28,12 +28,6 @@ #include "NativeVertexFormat.h" -#define ALPHATEST_PASS 2 -#define ALPHATEST_FAIL 1 -#define ALPHATEST_UNDETERMINED 0 - -static unsigned int AlphaPreTest(); - static void StageHash(int stage, u32* out) { out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24 @@ -119,7 +113,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo if (!enablePL) uid->values[0] |= xfregs.numTexGen.numTexGens << 11; // 4 - u32 alphaPreTest = AlphaPreTest(); + AlphaTest::TEST_RESULT alphaPreTest = bpmem.alpha_test.TestResult(); uid->values[0] |= alphaPreTest << 15; // 2 // numtexgens should be <= 8 @@ -153,11 +147,11 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo ptr += 4; // max: ptr = &uid->values[66] } - ptr[0] |= bpmem.alphaFunc.comp0; // 3 - ptr[0] |= bpmem.alphaFunc.comp1 << 3; // 3 - ptr[0] |= bpmem.alphaFunc.logic << 6; // 2 + ptr[0] |= bpmem.alpha_test.comp0; // 3 + ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3 + ptr[0] |= bpmem.alpha_test.logic << 6; // 2 - if (alphaPreTest != ALPHATEST_FAIL) + if (alphaPreTest != AlphaTest::FAIL) { ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3 ptr[0] |= bpmem.ztex2.op << 11; // 2 @@ -227,7 +221,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u ptr = &uid->values[112]; - *ptr++ = bpmem.alphaFunc.hex; // 112 + *ptr++ = bpmem.alpha_test.hex; // 112 *ptr++ = bpmem.fog.c_proj_fsel.hex; // 113 *ptr++ = bpmem.fogRange.Base.hex; // 114 @@ -719,8 +713,8 @@ const char *GeneratePixelShaderCode(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType WRITE(p, "prev = frac(prev * (255.0f/256.0f)) * (256.0f/255.0f);\n"); // TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state - int Pretest = AlphaPreTest(); - if (Pretest == ALPHATEST_UNDETERMINED) + AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); + if (Pretest == AlphaTest::UNDETERMINED) WriteAlphaTest(p, ApiType, dstAlphaMode); // the screen space depth value = far z + (clip z / clip w) * z range @@ -1149,48 +1143,6 @@ static const char *tevAlphaFunclogicTable[] = " == " // xnor }; -static unsigned int AlphaPreTest() -{ - u32 op = bpmem.alphaFunc.logic; - 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 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 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 ALPHATEST_PASS; - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) - 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 ALPHATEST_FAIL; - if ((comp[0] == ALPHACMP_ALWAYS && comp[1] == ALPHACMP_ALWAYS) || (comp[0] == ALPHACMP_NEVER && comp[1] == ALPHACMP_NEVER)) - return ALPHATEST_PASS; - break; - - default: PanicAlert("bad logic for alpha test? %08x", op); - } - return ALPHATEST_UNDETERMINED; -} - - static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode) { static const char *alphaRef[2] = @@ -1202,12 +1154,12 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode // using discard then return works the same in cg and dx9 but not in dx11 WRITE(p, "if(!( "); - int compindex = bpmem.alphaFunc.comp0 % 8; + int compindex = bpmem.alpha_test.comp0; WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[0]);//lookup the first component from the alpha function table - WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alphaFunc.logic % 4]);//lookup the logic op + WRITE(p, "%s", tevAlphaFunclogicTable[bpmem.alpha_test.logic]);//lookup the logic op - compindex = bpmem.alphaFunc.comp1 % 8; + compindex = bpmem.alpha_test.comp1; WRITE(p, tevAlphaFuncsTable[compindex],alphaRef[1]);//lookup the second component from the alpha function table WRITE(p, ")) {\n"); -- cgit v1.2.3 From be706a397720d94729518595339211ebc15be588 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 17:23:01 +0100 Subject: Disable color writing when alpha test always fails. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index b408b1bceb..88cf77631f 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -712,7 +712,6 @@ 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"); - // TODO: ALPHATEST_FAIL should be handled by disabling color writes in the render state AlphaTest::TEST_RESULT Pretest = bpmem.alpha_test.TestResult(); if (Pretest == AlphaTest::UNDETERMINED) WriteAlphaTest(p, ApiType, dstAlphaMode); -- cgit v1.2.3 From 4925a28f94d8a9925a85824ec89513c6774bdc30 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Tue, 8 Jan 2013 17:29:16 +0100 Subject: PixelShaderGen: Shader uid maintainance --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 88cf77631f..fdb5f21a51 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -151,23 +151,17 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo ptr[0] |= bpmem.alpha_test.comp1 << 3; // 3 ptr[0] |= bpmem.alpha_test.logic << 6; // 2 - if (alphaPreTest != AlphaTest::FAIL) - { - ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 8; // 3 - 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 + ptr[0] |= bpmem.ztex2.op << 8; // 2 + ptr[0] |= bpmem.zcontrol.early_ztest << 10; // 1 + ptr[0] |= bpmem.zmode.testenable << 11; // 1 + ptr[0] |= bpmem.zmode.updateenable << 12; // 1 if (dstAlphaMode != DSTALPHA_ALPHA_PASS) { if (bpmem.fog.c_proj_fsel.fsel != 0) { - ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1 - ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1 + ptr[0] |= bpmem.fog.c_proj_fsel.proj << 13; // 1 + ptr[0] |= bpmem.fogRange.Base.Enabled << 14; // 1 } } -- cgit v1.2.3 From ad05d568b9fce5f983dd06cfedb0904ada8ce9ab Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Fri, 11 Jan 2013 15:47:38 +0100 Subject: PixelShaderGen: Change error strings to be unique so that we can identify unexpected behavior more easily. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 36 +++++++++++++------------- 1 file changed, 18 insertions(+), 18 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index fdb5f21a51..f10fd437a8 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -287,10 +287,10 @@ static const char *tevKSelTableC[] = // KCSEL "0.375f,0.375f,0.375f", // 3_8 = 0x05 "0.25f,0.25f,0.25f", // 1_4 = 0x06 "0.125f,0.125f,0.125f", // 1_8 = 0x07 - "ERROR", // 0x08 - "ERROR", // 0x09 - "ERROR", // 0x0a - "ERROR", // 0x0b + "ERROR1", // 0x08 + "ERROR2", // 0x09 + "ERROR3", // 0x0a + "ERROR4", // 0x0b I_KCOLORS"[0].rgb", // K0 = 0x0C I_KCOLORS"[1].rgb", // K1 = 0x0D I_KCOLORS"[2].rgb", // K2 = 0x0E @@ -323,14 +323,14 @@ static const char *tevKSelTableA[] = // KASEL "0.375f",// 3_8 = 0x05 "0.25f", // 1_4 = 0x06 "0.125f",// 1_8 = 0x07 - "ERROR", // 0x08 - "ERROR", // 0x09 - "ERROR", // 0x0a - "ERROR", // 0x0b - "ERROR", // 0x0c - "ERROR", // 0x0d - "ERROR", // 0x0e - "ERROR", // 0x0f + "ERROR5", // 0x08 + "ERROR6", // 0x09 + "ERROR7", // 0x0a + "ERROR8", // 0x0b + "ERROR9", // 0x0c + "ERROR10", // 0x0d + "ERROR11", // 0x0e + "ERROR12", // 0x0f I_KCOLORS"[0].r", // K0_R = 0x10 I_KCOLORS"[1].r", // K1_R = 0x11 I_KCOLORS"[2].r", // K2_R = 0x12 @@ -405,7 +405,7 @@ static const char *tevCInputTable[] = // CC "float3(0.5f, 0.5f, 0.5f)", // HALF "(ckonsttemp.rgb)", //"konsttemp.rgb", // KONST "float3(0.0f, 0.0f, 0.0f)", // ZERO - "PADERROR", "PADERROR", "PADERROR", "PADERROR" + "PADERROR1", "PADERROR2", "PADERROR3", "PADERROR4" }; static const char *tevAInputTable[] = // CA @@ -427,17 +427,17 @@ static const char *tevAInputTable[] = // CA "crastemp", // RASA, "ckonsttemp", // KONST, (hw1 had quarter) "float4(0.0f, 0.0f, 0.0f, 0.0f)", // ZERO - "PADERROR", "PADERROR", "PADERROR", "PADERROR", - "PADERROR", "PADERROR", "PADERROR", "PADERROR", + "PADERROR5", "PADERROR6", "PADERROR7", "PADERROR8", + "PADERROR9", "PADERROR10", "PADERROR11", "PADERROR12", }; static const char *tevRasTable[] = { "colors_0", "colors_1", - "ERROR", //2 - "ERROR", //3 - "ERROR", //4 + "ERROR13", //2 + "ERROR14", //3 + "ERROR15", //4 "alphabump", // use bump alpha "(alphabump*(255.0f/248.0f))", //normalized "float4(0.0f, 0.0f, 0.0f, 0.0f)", // zero -- cgit v1.2.3 From dfc0c4b08d339502989fdfaf21e89f8ed77366a3 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 11 Jan 2013 19:38:04 -0500 Subject: Fix two signed/unsigned mismatch warnings. Also tidied up SDCardUtil - made the variables make more sense (typewise) --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index f10fd437a8..e21efa5ce1 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -28,7 +28,7 @@ #include "NativeVertexFormat.h" -static void StageHash(int stage, u32* out) +static void StageHash(u32 stage, u32* out) { out[0] |= bpmem.combiners[stage].colorC.hex & 0xFFFFFF; // 24 u32 alphaC = bpmem.combiners[stage].alphaC.hex & 0xFFFFF0; // 24, strip out tswap and rswap for now @@ -141,7 +141,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo } u32* ptr = &uid->values[2]; - for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) + for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1; ++i) { StageHash(i, ptr); ptr += 4; // max: ptr = &uid->values[66] @@ -204,7 +204,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.tevindref.hex; // 31 - for (int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times + for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times { *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i -- cgit v1.2.3 From 2cd415dd837d24e384524a7f0b39d547f890535f Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 11 Jan 2013 22:00:36 -0600 Subject: Fix the signed/unsigned comparison warnings created by a recent commit. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index e21efa5ce1..c1ebdbcc89 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -141,7 +141,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo } u32* ptr = &uid->values[2]; - for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1; ++i) + for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1u; ++i) { StageHash(i, ptr); ptr += 4; // max: ptr = &uid->values[66] @@ -204,7 +204,7 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *ptr++ = bpmem.tevindref.hex; // 31 - for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1; ++i) // up to 16 times + for (unsigned int i = 0; i < bpmem.genMode.numtevstages+1u; ++i) // up to 16 times { *ptr++ = bpmem.combiners[i].colorC.hex; // 32+5*i *ptr++ = bpmem.combiners[i].alphaC.hex; // 33+5*i -- cgit v1.2.3 From 6c0f6ffecff631344fe52972e267753e19e8d121 Mon Sep 17 00:00:00 2001 From: NeoBrainX Date: Sat, 19 Jan 2013 22:34:07 +0100 Subject: Fix a dumb regression from revision 4925a28f94d8. --- Source/Core/VideoCommon/Src/PixelShaderGen.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'Source/Core/VideoCommon/Src/PixelShaderGen.cpp') diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index c1ebdbcc89..448501aad0 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -158,10 +158,11 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo if (dstAlphaMode != DSTALPHA_ALPHA_PASS) { + ptr[0] |= bpmem.fog.c_proj_fsel.fsel << 13; // 3 if (bpmem.fog.c_proj_fsel.fsel != 0) { - ptr[0] |= bpmem.fog.c_proj_fsel.proj << 13; // 1 - ptr[0] |= bpmem.fogRange.Base.Enabled << 14; // 1 + ptr[0] |= bpmem.fog.c_proj_fsel.proj << 16; // 1 + ptr[0] |= bpmem.fogRange.Base.Enabled << 17; // 1 } } -- cgit v1.2.3