diff --git a/Source/Core/DolphinWX/VideoConfigDiag.cpp b/Source/Core/DolphinWX/VideoConfigDiag.cpp index d43c639842..6df2a83afc 100644 --- a/Source/Core/DolphinWX/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/VideoConfigDiag.cpp @@ -108,7 +108,6 @@ static wxString af_desc = wxTRANSLATE("Enable anisotropic filtering.\nEnhances v static wxString aa_desc = wxTRANSLATE("Reduces the amount of aliasing caused by rasterizing 3D graphics. This smooths out jagged edges on objects.\nIncreases GPU load and sometimes causes graphical issues. SSAA is significantly more demanding than MSAA, but provides top quality geometry anti-aliasing and also applies anti-aliasing to lighting, shader effects, and textures.\n\nIf unsure, select None."); static wxString scaled_efb_copy_desc = wxTRANSLATE("Greatly increases quality of textures generated using render-to-texture effects.\nRaising the internal resolution will improve the effect of this setting.\nSlightly increases GPU load and causes relatively few graphical issues.\n\nIf unsure, leave this checked."); static wxString pixel_lighting_desc = wxTRANSLATE("Calculates lighting of 3D objects per-pixel rather than per-vertex, smoothing out the appearance of lit polygons and making individual triangles less noticeable.\nRarely causes slowdowns or graphical issues.\n\nIf unsure, leave this unchecked."); -static wxString fast_depth_calc_desc = wxTRANSLATE("Use a less accurate algorithm to calculate depth values.\nCauses issues in a few games, but can give a decent speedup depending on the game and/or your GPU.\n\nIf unsure, leave this checked."); static wxString disable_bbox_desc = wxTRANSLATE("Disable the bounding box emulation.\nThis may improve the GPU performance a lot, but some games will break.\n\nIf unsure, leave this checked."); static wxString force_filtering_desc = wxTRANSLATE("Filter all textures, including any that the game explicitly set as unfiltered.\nMay improve quality of certain textures in some games, but will cause issues in others.\nOn Direct3D, setting Anisotropic Filtering above 1x will also have the same effect as enabling this option.\n\nIf unsure, leave this unchecked."); static wxString borderless_fullscreen_desc = wxTRANSLATE("Implement fullscreen mode with a borderless window spanning the whole screen instead of using exclusive mode.\nAllows for faster transitions between fullscreen and windowed mode, but slightly increases input latency, makes movement less smooth and slightly decreases performance.\nExclusive mode is required for Nvidia 3D Vision to work in the Direct3D backend.\n\nIf unsure, leave this unchecked."); @@ -517,7 +516,6 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con // - other hacks { wxGridSizer* const szr_other = new wxGridSizer(2, 5, 5); - szr_other->Add(CreateCheckBox(page_hacks, _("Fast Depth Calculation"), wxGetTranslation(fast_depth_calc_desc), vconfig.bFastDepthCalc)); szr_other->Add(CreateCheckBox(page_hacks, _("Disable Bounding Box"), wxGetTranslation(disable_bbox_desc), vconfig.bBBoxEnable, true)); wxStaticBoxSizer* const group_other = new wxStaticBoxSizer(wxVERTICAL, page_hacks, _("Other")); diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index f9781c5217..09f8c6a871 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -285,13 +285,14 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) GenerateVSOutputMembers(out, ApiType); out.Write("};\n"); + const bool forced_slow_depth = g_ActiveConfig.bForcedSlowDepth || !g_ActiveConfig.backend_info.bSupportsClipControl; const bool forced_early_z = g_ActiveConfig.backend_info.bSupportsEarlyZ && bpmem.UseEarlyDepthTest() - && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) + && (!forced_slow_depth || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED) // We can't allow early_ztest for zfreeze because depth is overridden per-pixel. // This means it's impossible for zcomploc to be emulated on a zfrozen polygon. && !(bpmem.zmode.testenable && bpmem.genMode.zfreeze); const bool per_pixel_depth = (bpmem.ztex2.op != ZTEXTURE_DISABLE && bpmem.UseLateDepthTest()) - || (!g_ActiveConfig.bFastDepthCalc && bpmem.zmode.testenable && !forced_early_z) + || (forced_slow_depth && bpmem.zmode.testenable && !forced_early_z) || (bpmem.zmode.testenable && bpmem.genMode.zfreeze); if (forced_early_z) @@ -324,7 +325,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) // D3D11 also has a way to force the driver to enable early-z, so we're fine here. if(ApiType == API_OPENGL) { - // This is a #define which signals whatever early-z method the driver supports. + // This is a #define which signals whatever early-z method the driver supports. out.Write("FORCE_EARLY_Z; \n"); } else @@ -332,7 +333,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) out.Write("[earlydepthstencil]\n"); } } - else if (bpmem.UseEarlyDepthTest() && (g_ActiveConfig.bFastDepthCalc || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED)) + else if (bpmem.UseEarlyDepthTest() && (!forced_slow_depth || bpmem.alpha_test.TestResult() == AlphaTest::UNDETERMINED)) { static bool warn_once = true; if (warn_once) @@ -561,11 +562,13 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) out.Write("\tint zCoord = int(" I_ZSLOPE".z + " I_ZSLOPE".x * screenpos.x + " I_ZSLOPE".y * screenpos.y);\n"); } - else if (!g_ActiveConfig.bFastDepthCalc) + else if (forced_slow_depth) { - // FastDepth means to trust the depth generated in perspective division. - // It should be correct, but it seems not to be as accurate as required. TODO: Find out why! - // For disabled FastDepth we just calculate the depth value again. + // Due to floating point round-trip issues some depth equations are not as accurate as required. + // Depth equations used in D3D and OGL with GL_ARB_clip_control are accurate, but older cards + // that do not support GL_ARB_clip_control are not accurate enough under OGL. So on these older + // cards we just calculate the depth value again. + // The performance impact of this additional calculation doesn't matter, but it prevents // the host GPU driver from performing any early depth test optimizations. out.SetConstantsUsed(C_ZBIAS+1, C_ZBIAS+1); @@ -574,6 +577,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) } else { + // Our D3D backend uses inverse depth values, so we invert them to the expected value here. if (ApiType == API_D3D) out.Write("\tint zCoord = int((1.0 - rawpos.z) * 16777216.0);\n"); else @@ -587,7 +591,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) uid_data->ztex_op = bpmem.ztex2.op; uid_data->per_pixel_depth = per_pixel_depth; uid_data->forced_early_z = forced_early_z; - uid_data->fast_depth_calc = g_ActiveConfig.bFastDepthCalc; + uid_data->forced_slow_depth = forced_slow_depth; uid_data->early_ztest = bpmem.UseEarlyDepthTest(); uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel; uid_data->zfreeze = bpmem.genMode.zfreeze; @@ -595,6 +599,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) // Note: z-textures are not written to depth buffer if early depth test is used if (per_pixel_depth && bpmem.UseEarlyDepthTest()) { + // Our D3D backend uses inverse depth values, so we invert them back to the depth buffer value here. if (ApiType == API_D3D) out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n"); else @@ -614,6 +619,7 @@ static T GeneratePixelShader(DSTALPHA_MODE dstAlphaMode, API_TYPE ApiType) if (per_pixel_depth && bpmem.UseLateDepthTest()) { + // Our D3D backend uses inverse depth values, so we invert them back to the depth buffer value here. if (ApiType == API_D3D) out.Write("\tdepth = 1.0 - float(zCoord) / 16777216.0;\n"); else diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index 3cc8071ce9..66611d82b1 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -42,7 +42,7 @@ struct pixel_shader_uid_data u32 fog_fsel : 3; u32 fog_RangeBaseEnabled : 1; u32 ztex_op : 2; - u32 fast_depth_calc : 1; + u32 forced_slow_depth : 1; u32 per_pixel_depth : 1; u32 forced_early_z : 1; u32 early_ztest : 1; diff --git a/Source/Core/VideoCommon/VertexShaderGen.cpp b/Source/Core/VideoCommon/VertexShaderGen.cpp index ad99b445c0..9518aa9dbf 100644 --- a/Source/Core/VideoCommon/VertexShaderGen.cpp +++ b/Source/Core/VideoCommon/VertexShaderGen.cpp @@ -333,7 +333,7 @@ static T GenerateVertexShader(API_TYPE api_type) else // OGL { // this results in a scale from -1..0 to -1..1 after perspective - // divide + // divide, but introduces a floating point round-trip error. out.Write("o.pos.z = o.pos.z * -2.0 - o.pos.w;\n"); // the next steps of the OGL pipeline are: diff --git a/Source/Core/VideoCommon/VideoConfig.cpp b/Source/Core/VideoCommon/VideoConfig.cpp index 257cc61fc6..4a4f9a3f53 100644 --- a/Source/Core/VideoCommon/VideoConfig.cpp +++ b/Source/Core/VideoCommon/VideoConfig.cpp @@ -71,7 +71,7 @@ void VideoConfig::Load(const std::string& ini_file) settings->Get("FreeLook", &bFreeLook, 0); settings->Get("UseFFV1", &bUseFFV1, 0); settings->Get("EnablePixelLighting", &bEnablePixelLighting, 0); - settings->Get("FastDepthCalc", &bFastDepthCalc, true); + settings->Get("ForcedSlowDepth", &bForcedSlowDepth, false); settings->Get("MSAA", &iMultisamples, 1); settings->Get("SSAA", &bSSAA, false); settings->Get("EFBScale", &iEFBScale, (int)SCALE_1X); // native @@ -165,7 +165,7 @@ void VideoConfig::GameIniLoad() CHECK_SETTING("Video_Settings", "ConvertHiresTextures", bConvertHiresTextures); CHECK_SETTING("Video_Settings", "CacheHiresTextures", bCacheHiresTextures); CHECK_SETTING("Video_Settings", "EnablePixelLighting", bEnablePixelLighting); - CHECK_SETTING("Video_Settings", "FastDepthCalc", bFastDepthCalc); + CHECK_SETTING("Video_Settings", "ForcedSlowDepth", bForcedSlowDepth); CHECK_SETTING("Video_Settings", "MSAA", iMultisamples); CHECK_SETTING("Video_Settings", "SSAA", bSSAA); @@ -282,7 +282,7 @@ void VideoConfig::Save(const std::string& ini_file) settings->Set("FreeLook", bFreeLook); settings->Set("UseFFV1", bUseFFV1); settings->Set("EnablePixelLighting", bEnablePixelLighting); - settings->Set("FastDepthCalc", bFastDepthCalc); + settings->Set("ForcedSlowDepth", bForcedSlowDepth); settings->Set("MSAA", iMultisamples); settings->Set("SSAA", bSSAA); settings->Set("EFBScale", iEFBScale); diff --git a/Source/Core/VideoCommon/VideoConfig.h b/Source/Core/VideoCommon/VideoConfig.h index bc0250ab2f..adfa20f65b 100644 --- a/Source/Core/VideoCommon/VideoConfig.h +++ b/Source/Core/VideoCommon/VideoConfig.h @@ -117,7 +117,7 @@ struct VideoConfig final std::string sPhackvalue[2]; float fAspectRatioHackW, fAspectRatioHackH; bool bEnablePixelLighting; - bool bFastDepthCalc; + bool bForcedSlowDepth; int iLog; // CONF_ bits int iSaveTargetId; // TODO: Should be dropped