From 402006a83a89bc0f790934096e915f0e8c23f808 Mon Sep 17 00:00:00 2001 From: rodolfoosvaldobogado Date: Thu, 29 Mar 2012 18:26:58 -0300 Subject: [PATCH] more fixes to zcomplock and opengl implementation --- Source/Core/Common/Src/LinearDiskCache.h | 2 +- Source/Core/DolphinWX/Src/VideoConfigDiag.cpp | 6 +-- .../Core/VideoCommon/Src/PixelShaderGen.cpp | 38 +++++++++---------- Source/Core/VideoCommon/Src/VideoConfig.cpp | 8 ++-- Source/Core/VideoCommon/Src/VideoConfig.h | 2 +- Source/Plugins/Plugin_VideoDX9/Src/Render.cpp | 3 +- .../Plugin_VideoDX9/Src/VertexManager.cpp | 2 +- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 37 ++++++++++++++++++ Source/Plugins/Plugin_VideoOGL/Src/Render.h | 5 +-- .../Plugin_VideoOGL/Src/VertexManager.cpp | 25 ++++++++---- 10 files changed, 86 insertions(+), 42 deletions(-) diff --git a/Source/Core/Common/Src/LinearDiskCache.h b/Source/Core/Common/Src/LinearDiskCache.h index 11d0a2ced8..2327caecd2 100644 --- a/Source/Core/Common/Src/LinearDiskCache.h +++ b/Source/Core/Common/Src/LinearDiskCache.h @@ -24,7 +24,7 @@ // Increment this every time you change shader generation code. enum { - LINEAR_DISKCACHE_VER = 6984 + LINEAR_DISKCACHE_VER = 6989 }; // On disk format: diff --git a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp index 7678e165c8..852de9f880 100644 --- a/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp +++ b/Source/Core/DolphinWX/Src/VideoConfigDiag.cpp @@ -87,7 +87,7 @@ wxString fast_mipmaps_desc = wxTRANSLATE("Automatically generate mipmaps rather 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 decreases performance and possibly causes issues (although unlikely).\n\nIf unsure, leave this checked."); wxString pixel_lighting_desc = wxTRANSLATE("Calculate lighting of 3D graphics per-pixel rather than per vertex.\nDecreases emulation speed by some percent (depending on your GPU).\nThis usually is a safe enhancement, but might cause issues sometimes.\n\nIf unsure, leave this unchecked."); wxString pixel_depth_desc = wxTRANSLATE("Calculate depth values of 3D graphics per-pixel rather than per vertex.\nIn contrast to pixel lighting (which is merely an enhancement), per-pixel depth calculations are necessary to properly emulate a small number of games.\n\nIf unsure, leave this checked."); -wxString acurate_zcomploc_desc = wxTRANSLATE("Emulate zcomplock witha multi-pass approach. Slower."); +wxString fast_zcomploc_desc = wxTRANSLATE("Disabled emulation of zcomploc (a feature used for rendering certain effects).\nSpeeds up emulation, but also breaks games that rely on this functionality.\nIf unsure, leave this unchecked."); wxString force_filtering_desc = wxTRANSLATE("Force texture filtering even if the emulated game explicitly disabled it.\nImproves texture quality slightly but causes glitches in some games.\n\nIf unsure, leave this unchecked."); wxString _3d_vision_desc = wxTRANSLATE("Enable 3D effects via stereoscopy using Nvidia 3D Vision technology if it's supported by your GPU.\nPossibly causes issues.\nRequires fullscreen to work.\n\nIf unsure, leave this unchecked."); wxString internal_res_desc = wxTRANSLATE("Specifies the resolution used to render at. A high resolution will improve visual quality a lot but is also quite heavy on performance and might cause glitches in certain games.\n\"Multiple of 640x528\" is a bit slower than \"Window Size\" but yields less issues. Generally speaking, the lower the internal resolution is, the better your performance will be.\n\nIf unsure, select 640x528."); @@ -496,8 +496,8 @@ VideoConfigDiag::VideoConfigDiag(wxWindow* parent, const std::string &title, con szr_other->Add(CreateCheckBox(page_hacks, _("Cache Display Lists"), wxGetTranslation(dlc_desc), vconfig.bDlistCachingEnable)); szr_other->Add(CreateCheckBox(page_hacks, _("Disable Lighting"), wxGetTranslation(disable_lighting_desc), vconfig.bDisableLighting)); szr_other->Add(CreateCheckBox(page_hacks, _("Disable Fog"), wxGetTranslation(disable_fog_desc), vconfig.bDisableFog)); - szr_other->Add(CreateCheckBox(page_hacks, _("Disable Per-Pixel Depth"), wxGetTranslation(pixel_depth_desc), vconfig.bEnablePerPixelDepth, true)); - szr_other->Add(CreateCheckBox(page_hacks, _("Acurate Zcomploc emulation"), wxGetTranslation(acurate_zcomploc_desc), vconfig.bAcurateZcomploc, true)); + szr_other->Add(CreateCheckBox(page_hacks, _("Enable Per-Pixel Depth"), wxGetTranslation(pixel_depth_desc), vconfig.bEnablePerPixelDepth, true)); + szr_other->Add(CreateCheckBox(page_hacks, _("Fast Zcomploc emulation"), wxGetTranslation(fast_zcomploc_desc), vconfig.bEnableFastZcomploc)); szr_other->Add(CreateCheckBox(page_hacks, _("Skip Dest. Alpha Pass"), wxGetTranslation(disable_alphapass_desc), vconfig.bDstAlphaPass)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenCL Texture Decoder"), wxGetTranslation(opencl_desc), vconfig.bEnableOpenCL)); szr_other->Add(CreateCheckBox(page_hacks, _("OpenMP Texture Decoder"), wxGetTranslation(omp_desc), vconfig.bOMPDecoder)); diff --git a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp index 7d8a3734da..5340b84f1a 100644 --- a/Source/Core/VideoCommon/Src/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/Src/PixelShaderGen.cpp @@ -177,7 +177,7 @@ void GetPixelShaderId(PIXELSHADERUID *uid, DSTALPHA_MODE dstAlphaMode, u32 compo ptr[0] |= bpmem.zcontrol.zcomploc << 13; // 1 ptr[0] |= bpmem.zmode.testenable << 14; // 1 ptr[0] |= bpmem.zmode.updateenable << 15; // 1 - ptr[0] |= g_ActiveConfig.bAcurateZcomploc << 16; // 1 + ptr[0] |= g_ActiveConfig.bEnableFastZcomploc << 16; // 1 } } @@ -212,7 +212,8 @@ void GetSafePixelShaderId(PIXELSHADERUIDSAFE *uid, DSTALPHA_MODE dstAlphaMode, u *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.bEnableFastZcomploc ; // 7 + *ptr++ = xfregs.numTexGen.hex; // 8 if (g_ActiveConfig.bEnablePixelLighting && g_ActiveConfig.backend_info.bSupportsPixelLighting) { @@ -224,28 +225,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; // 9-16 for (unsigned int i = 0; i < 16; ++i) - *ptr++ = bpmem.tevind[i].hex; // 16-31 + *ptr++ = bpmem.tevind[i].hex; // 17-32 - *ptr++ = bpmem.tevindref.hex; // 32 + *ptr++ = bpmem.tevindref.hex; // 33 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; // 34+5*i + *ptr++ = bpmem.combiners[i].alphaC.hex; // 35+5*i + *ptr++ = bpmem.tevind[i].hex; // 36+5*i + *ptr++ = bpmem.tevksel[i/2].hex; // 37+5*i + *ptr++ = bpmem.tevorders[i/2].hex; // 38+5*i } - ptr = &uid->values[113]; + ptr = &uid->values[114]; - *ptr++ = bpmem.alphaFunc.hex; // 113 + *ptr++ = bpmem.alphaFunc.hex; // 114 - *ptr++ = bpmem.fog.c_proj_fsel.hex; // 114 - *ptr++ = bpmem.fogRange.Base.hex; // 115 + *ptr++ = bpmem.fog.c_proj_fsel.hex; // 115 + *ptr++ = bpmem.fogRange.Base.hex; // 116 _assert_((ptr - uid->values) == uid->GetNumValues()); } @@ -1191,12 +1192,9 @@ static void WriteAlphaTest(char *&p, API_TYPE ApiType,DSTALPHA_MODE dstAlphaMode // when the alpha test fail. This is not a correct implementation because // even if the depth test fails the fragment could be alpha blended. // the more correct, but slow, way 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 an update only the pixels - // updated by the depth pass - - if (!(bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable) || g_ActiveConfig.bAcurateZcomploc) + // 1 - if zcomplock is enabled make a last pass, with color channel write disabled updating only + // depth channel. + if (!(g_ActiveConfig.bEnableFastZcomploc && bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable)) { WRITE(p, "discard;\n"); if (ApiType != API_D3D11) diff --git a/Source/Core/VideoCommon/Src/VideoConfig.cpp b/Source/Core/VideoCommon/Src/VideoConfig.cpp index b04aa0d9cf..5eb293251d 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.cpp +++ b/Source/Core/VideoCommon/Src/VideoConfig.cpp @@ -76,7 +76,7 @@ void VideoConfig::Load(const char *ini_file) iniFile.Get("Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle, 0); iniFile.Get("Settings", "EnablePixelLighting", &bEnablePixelLighting, 0); iniFile.Get("Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth, 0); - iniFile.Get("Settings", "AcurateZcomploc", &bAcurateZcomploc, 0); + iniFile.Get("Settings", "EnableFastZcomploc", &bEnableFastZcomploc, 0); iniFile.Get("Settings", "MSAA", &iMultisampleMode, 0); iniFile.Get("Settings", "EFBScale", &iEFBScale, 2); // native @@ -139,7 +139,7 @@ void VideoConfig::GameIniLoad(const char *ini_file) iniFile.GetIfExists("Video_Settings", "AnaglyphFocalAngle", &iAnaglyphFocalAngle); iniFile.GetIfExists("Video_Settings", "EnablePixelLighting", &bEnablePixelLighting); iniFile.GetIfExists("Video_Settings", "EnablePerPixelDepth", &bEnablePerPixelDepth); - iniFile.GetIfExists("Video_Settings", "AcurateZcomploc", &bAcurateZcomploc); + iniFile.GetIfExists("Video_Settings", "EnableFastZcomploc", &bEnableFastZcomploc); iniFile.GetIfExists("Video_Settings", "MSAA", &iMultisampleMode); iniFile.GetIfExists("Video_Settings", "EFBScale", &iEFBScale); // integral iniFile.GetIfExists("Video_Settings", "DstAlphaPass", &bDstAlphaPass); @@ -211,7 +211,7 @@ void VideoConfig::Save(const char *ini_file) iniFile.Set("Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); iniFile.Set("Settings", "EnablePixelLighting", bEnablePixelLighting); iniFile.Set("Settings", "EnablePerPixelDepth", bEnablePerPixelDepth); - iniFile.Set("Settings", "AcurateZcomploc", bAcurateZcomploc); + iniFile.Set("Settings", "EnableFastZcomploc", bEnableFastZcomploc); iniFile.Set("Settings", "ShowEFBCopyRegions", bShowEFBCopyRegions); @@ -281,7 +281,7 @@ void VideoConfig::GameIniSave(const char* default_ini, const char* game_ini) SET_IF_DIFFERS("Video_Settings", "AnaglyphFocalAngle", iAnaglyphFocalAngle); SET_IF_DIFFERS("Video_Settings", "EnablePixelLighting", bEnablePixelLighting); SET_IF_DIFFERS("Video_Settings", "EnablePerPixelDepth", bEnablePerPixelDepth); - SET_IF_DIFFERS("Video_Settings", "AcurateZcomploc", bAcurateZcomploc); + SET_IF_DIFFERS("Video_Settings", "EnableFastZcomploc", bEnableFastZcomploc); SET_IF_DIFFERS("Video_Settings", "MSAA", iMultisampleMode); SET_IF_DIFFERS("Video_Settings", "EFBScale", iEFBScale); // integral SET_IF_DIFFERS("Video_Settings", "DstAlphaPass", bDstAlphaPass); diff --git a/Source/Core/VideoCommon/Src/VideoConfig.h b/Source/Core/VideoCommon/Src/VideoConfig.h index e330de54ad..d6dc3cefe0 100644 --- a/Source/Core/VideoCommon/Src/VideoConfig.h +++ b/Source/Core/VideoCommon/Src/VideoConfig.h @@ -137,7 +137,7 @@ struct VideoConfig bool bUseBBox; bool bEnablePixelLighting; bool bEnablePerPixelDepth; - bool bAcurateZcomploc; + bool bEnableFastZcomploc; int iLog; // CONF_ bits int iSaveTargetId; diff --git a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp index 5d836ec6ed..d3de48b190 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/Render.cpp @@ -1211,7 +1211,7 @@ void Renderer::ApplyState(RenderStateMode mode) D3D::ChangeRenderState(D3DRS_COLORWRITEENABLE, 0); } else if(mode == RSM_Multipass) - { + { D3D::ChangeRenderState(D3DRS_ZENABLE, TRUE); D3D::ChangeRenderState(D3DRS_ZWRITEENABLE, false); D3D::ChangeRenderState(D3DRS_ZFUNC, D3DCMP_EQUAL); @@ -1231,6 +1231,7 @@ void Renderer::RestoreState(RenderStateMode mode) } else if(mode == RSM_Multipass) { + D3D::RefreshRenderState(D3DRS_ALPHABLENDENABLE); D3D::RefreshRenderState(D3DRS_ZENABLE); D3D::RefreshRenderState(D3DRS_ZWRITEENABLE); D3D::RefreshRenderState(D3DRS_ZFUNC); diff --git a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp index 8dd13f3e3b..af5bc3c839 100644 --- a/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoDX9/Src/VertexManager.cpp @@ -191,7 +191,7 @@ void VertexManager::vFlush() g_renderer->RestoreState(RSM_Multipass); } - bool UseZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && g_ActiveConfig.bAcurateZcomploc; + bool UseZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && !g_ActiveConfig.bEnableFastZcomploc; if (UseZcomploc) { diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 9883d35fbb..6b0a3f1481 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -632,6 +632,43 @@ void Renderer::SetScissorRect(const TargetRectangle& rc) glScissor(rc.left, rc.bottom, rc.GetWidth(), rc.GetHeight()); } +void Renderer::ApplyState(RenderStateMode mode) +{ + if(mode == RSM_Zcomploc) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + } + else if(mode == RSM_Multipass) + { + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + glDepthFunc(GL_EQUAL); + } + else if (mode == RSM_UseDstAlpha) + { + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + glDisable(GL_BLEND); + } +} + +void Renderer::RestoreState(RenderStateMode mode) +{ + if(mode == RSM_Zcomploc) + { + SetColorMask(); + } + else if(mode == RSM_Multipass) + { + SetDepthMode(); + } + else if (mode == RSM_UseDstAlpha) + { + SetColorMask(); + if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) + glEnable(GL_BLEND); + } +} + void Renderer::SetColorMask() { // Only enable alpha channel if it's supported by the current EFB format diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.h b/Source/Plugins/Plugin_VideoOGL/Src/Render.h index 5a184dceeb..ca87adea6b 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.h @@ -26,9 +26,8 @@ public: void SetSamplerState(int stage,int texindex); void SetInterlacingMode(); - // TODO: Implement and use these - void ApplyState(RenderStateMode mode){} - void RestoreState(RenderStateMode mode){} + void ApplyState(RenderStateMode mode); + void RestoreState(RenderStateMode mode); void RenderText(const char* pstr, int left, int top, u32 color); void DrawDebugInfo(); diff --git a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp index dff7f8299e..dacb0f3b0e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/VertexManager.cpp @@ -224,17 +224,26 @@ void VertexManager::vFlush() ps = PixelShaderCache::SetShader(DSTALPHA_ALPHA_PASS,g_nativeVertexFmt->m_components); if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); - // only update alpha - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - - glDisable(GL_BLEND); + g_renderer->ApplyState(RSM_UseDstAlpha); + if (bpmem.zmode.updateenable) + g_renderer->ApplyState(RSM_Multipass); Draw(); - // restore color mask - g_renderer->SetColorMask(); + + g_renderer->RestoreState(RSM_UseDstAlpha); + if (bpmem.zmode.updateenable) + g_renderer->RestoreState(RSM_Multipass); + } - if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) - glEnable(GL_BLEND); + bool UseZcomploc = bpmem.zcontrol.zcomploc && bpmem.zmode.updateenable && !g_ActiveConfig.bEnableFastZcomploc; + + if (UseZcomploc) + { + FRAGMENTSHADER* ps = PixelShaderCache::SetShader(DSTALPHA_ZCOMPLOC,g_nativeVertexFmt->m_components); + if (ps) PixelShaderCache::SetCurrentShader(ps->glprogid); + g_renderer->ApplyState(RSM_Zcomploc); + Draw(); + g_renderer->RestoreState(RSM_Zcomploc); } GFX_DEBUGGER_PAUSE_AT(NEXT_FLUSH, true);