diff --git a/plugins/GSdx/GSdx.rc b/plugins/GSdx/GSdx.rc index 38dbaedf46..234b6f3c0d 100644 --- a/plugins/GSdx/GSdx.rc +++ b/plugins/GSdx/GSdx.rc @@ -318,14 +318,13 @@ BEGIN COMBOBOX IDC_CRC_LEVEL,105,222,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP CONTROL "Enable HW Hacks",IDC_HACKS_ENABLED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,240,71,10 PUSHBUTTON "Advanced Settings and Hacks",IDC_HACKSBUTTON,105,237,127,14 - // OpenGL (Hardware) Settings: LTEXT "Accurate Date:",IDC_ACCURATE_DATE_TEXT,22,255,79,8 COMBOBOX IDC_ACCURATE_DATE,105,253,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Blending Unit Accuracy:",IDC_ACCURATE_BLEND_UNIT_TEXT,22,271,79,8 COMBOBOX IDC_ACCURATE_BLEND_UNIT,105,269,127,118,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP // Direct3D 9 (Hardware) Settings: - CONTROL "Alpha Correction",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,256,74,8 - CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,256,90,8 + CONTROL "Alpha Correction",IDC_FBA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,271,74,10 + CONTROL "Logarithmic Z",IDC_LOGZ,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,105,271,90,10 // Software Renderer Settings: GROUPBOX "Software Renderer Settings",IDC_STATIC,6,295,231,40,BS_CENTER CONTROL "Edge Anti-aliasing (AA1)",IDC_AA1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,306,91,10 diff --git a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp index 0dc67a5c60..3cae071df0 100644 --- a/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp +++ b/plugins/GSdx/Renderers/DX11/GSTextureFX11.cpp @@ -343,11 +343,11 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uin dsd.StencilReadMask = 1; dsd.StencilWriteMask = 1; dsd.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL; - dsd.FrontFace.StencilPassOp = dssel.alpha_stencil ? D3D11_STENCIL_OP_ZERO : D3D11_STENCIL_OP_KEEP; + dsd.FrontFace.StencilPassOp = dssel.date_one ? D3D11_STENCIL_OP_ZERO : D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFunc = D3D11_COMPARISON_EQUAL; - dsd.BackFace.StencilPassOp = dssel.alpha_stencil ? D3D11_STENCIL_OP_ZERO : D3D11_STENCIL_OP_KEEP; + dsd.BackFace.StencilPassOp = dssel.date_one ? D3D11_STENCIL_OP_ZERO : D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP; } diff --git a/plugins/GSdx/Renderers/DX9/GSTextureFX9.cpp b/plugins/GSdx/Renderers/DX9/GSTextureFX9.cpp index 786d2b2244..877f9485d7 100644 --- a/plugins/GSdx/Renderers/DX9/GSTextureFX9.cpp +++ b/plugins/GSdx/Renderers/DX9/GSTextureFX9.cpp @@ -250,10 +250,10 @@ void GSDevice9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint { dss->StencilEnable = true; dss->StencilReadMask = 1; - dss->StencilWriteMask = dssel.alpha_stencil ? 3 : 2; + dss->StencilWriteMask = dssel.date_one ? 3 : 2; dss->StencilFunc = dssel.date ? D3DCMP_EQUAL : D3DCMP_ALWAYS; - dss->StencilPassOp = dssel.alpha_stencil ? D3DSTENCILOP_ZERO : dssel.fba ? D3DSTENCILOP_REPLACE : D3DSTENCILOP_KEEP; - dss->StencilFailOp = dssel.fba && !dssel.alpha_stencil ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP; + dss->StencilPassOp = dssel.date_one ? D3DSTENCILOP_ZERO : dssel.fba ? D3DSTENCILOP_REPLACE : D3DSTENCILOP_KEEP; + dss->StencilFailOp = dssel.fba && !dssel.date_one ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP; dss->StencilDepthFailOp = D3DSTENCILOP_KEEP; dss->StencilRef = 3; } diff --git a/plugins/GSdx/Renderers/DXCommon/GSDeviceDX.h b/plugins/GSdx/Renderers/DXCommon/GSDeviceDX.h index 4306757b81..e6c0d322f7 100644 --- a/plugins/GSdx/Renderers/DXCommon/GSDeviceDX.h +++ b/plugins/GSdx/Renderers/DXCommon/GSDeviceDX.h @@ -247,7 +247,7 @@ public: uint32 zwe:1; uint32 date:1; uint32 fba:1; - uint32 alpha_stencil:1; + uint32 date_one:1; }; uint32 key; diff --git a/plugins/GSdx/Renderers/DXCommon/GSRendererDX.cpp b/plugins/GSdx/Renderers/DXCommon/GSRendererDX.cpp index 939c20a25a..03c64dd378 100644 --- a/plugins/GSdx/Renderers/DXCommon/GSRendererDX.cpp +++ b/plugins/GSdx/Renderers/DXCommon/GSRendererDX.cpp @@ -402,6 +402,55 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc EmulateTextureShuffleAndFbmask(); + // DATE: selection of the algorithm. + + if (DATE) + { + if (!UserHacks_AlphaStencil && m_om_bsel.wa && !m_context->TEST.ATE) + { + // Performance note: check alpha range with GetAlphaMinMax() + GetAlphaMinMax(); + if (m_context->TEST.DATM && m_vt.m_alpha.max < 128) + { + // Only first pixel (write 0) will pass (alpha is 1) + // fprintf(stderr, "Fast DATE with alpha %d-%d\n", m_vt.m_alpha.min, m_vt.m_alpha.max); + m_om_dssel.date_one = 1; + } + else if (!m_context->TEST.DATM && m_vt.m_alpha.min >= 128) + { + // Only first pixel (write 1) will pass (alpha is 0) + // fprintf(stderr, "Fast DATE with alpha %d-%d\n", m_vt.m_alpha.min, m_vt.m_alpha.max); + m_om_dssel.date_one = 1; + } + else if ((m_vt.m_primclass == GS_SPRITE_CLASS /*&& m_drawlist.size() < 50*/) || (m_index.tail < 100)) + { + // Direct3D doesn't support Slow DATE_GL45. + // Let's leave the check to ensure DATE_one is emulated properly on Fast Accurate DATE. + // m_drawlist.size() isn't supported on D3D so there will be more games hitting this code path, + // it should be fine with regular DATE since originally it ran with anyway. + // Note: Potentially Alpha Stencil might emulate SLOW DATE properly. Perhaps some of the code can be implemented here. + // fprintf(stderr, "Slow DATE with alpha %d-%d is not supported\n", m_vt.m_alpha.min, m_vt.m_alpha.max); + } + else + { + if (m_accurate_date) + { + // fprintf(stderr, "Fast Accurate DATE with alpha %d-%d\n", m_vt.m_alpha.min, m_vt.m_alpha.max); + m_om_dssel.date_one = 1; + } + else + { + // DATE is already true, no need for another check. + // fprintf(stderr, "Inaccurate DATE with alpha %d-%d\n", m_vt.m_alpha.min, m_vt.m_alpha.max); + } + } + } + else if (!m_om_bsel.wa && !m_context->TEST.ATE) + { + // TODO: is it legal ? Likely but it need to be tested carefully. + } + } + // Blend if (!IsOpaque()) @@ -638,7 +687,7 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc ps_cb.FogColor_AREF.a = (float)0x80; } if (!(m_context->FBA.FBA && m_context->TEST.DATM == 1)) - m_om_dssel.alpha_stencil = 1; + m_om_dssel.date_one = 1; } if (tex) diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp index 74f413ac5f..5c7c8386b5 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.cpp +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.cpp @@ -39,6 +39,7 @@ GSRendererHW::GSRendererHW(GSTextureCache* tc) m_mipmap = theApp.GetConfigI("mipmap_hw"); m_upscale_multiplier = theApp.GetConfigI("upscale_multiplier"); m_large_framebuffer = theApp.GetConfigB("large_framebuffer"); + m_accurate_date = theApp.GetConfigI("accurate_date"); if (theApp.GetConfigB("UserHacks")) { m_userhacks_align_sprite_X = theApp.GetConfigB("UserHacks_align_sprite_X"); m_userhacks_round_sprite_offset = theApp.GetConfigI("UserHacks_round_sprite_offset"); diff --git a/plugins/GSdx/Renderers/HW/GSRendererHW.h b/plugins/GSdx/Renderers/HW/GSRendererHW.h index 95901cbca1..a85231a71b 100644 --- a/plugins/GSdx/Renderers/HW/GSRendererHW.h +++ b/plugins/GSdx/Renderers/HW/GSRendererHW.h @@ -154,6 +154,8 @@ protected: float m_userhacks_tcoffset_x; float m_userhacks_tcoffset_y; + int m_accurate_date; + bool m_channel_shuffle; GSVector2i m_lod; // Min & Max level of detail diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp index 4e7ca72332..196753d662 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.cpp @@ -27,7 +27,6 @@ GSRendererOGL::GSRendererOGL() : GSRendererHW(new GSTextureCacheOGL(this)) { - m_accurate_date = theApp.GetConfigI("accurate_date"); m_sw_blending = theApp.GetConfigI("accurate_blending_unit"); // Hope nothing requires too many draw calls. diff --git a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h index 662cae8d4d..e6702e3158 100644 --- a/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h +++ b/plugins/GSdx/Renderers/OpenGL/GSRendererOGL.h @@ -51,7 +51,6 @@ class GSRendererOGL final : public GSRendererHW }; private: - int m_accurate_date; int m_sw_blending; PRIM_OVERLAP m_prim_overlap; std::vector m_drawlist; diff --git a/plugins/GSdx/Window/GSSetting.cpp b/plugins/GSdx/Window/GSSetting.cpp index 514b2e7aab..568e459e39 100644 --- a/plugins/GSdx/Window/GSSetting.cpp +++ b/plugins/GSdx/Window/GSSetting.cpp @@ -112,7 +112,8 @@ const char* dialog_message(int ID, bool* updateText) { "Most of the time this option should be enough.\n" "This is the recommended setting.\n\n" "Full:\nSlower but fully emulates destination alpha testing.\n" - "Not needed unless Fast mode isn't enough."; + "Not needed unless Fast mode isn't enough.\n\n" + "Note: Full mode is not available on Direct3D."; case IDC_ACCURATE_BLEND_UNIT: return "Control the accuracy level of the GS blending unit emulation.\n\n" "None:\nFast but introduces various rendering issues.\n" diff --git a/plugins/GSdx/Window/GSSettingsDlg.cpp b/plugins/GSdx/Window/GSSettingsDlg.cpp index 0bb1e44394..9b5a245fca 100644 --- a/plugins/GSdx/Window/GSSettingsDlg.cpp +++ b/plugins/GSdx/Window/GSSettingsDlg.cpp @@ -396,8 +396,6 @@ void GSSettingsDlg::UpdateControls() ShowWindow(GetDlgItem(m_hWnd, IDC_LOGZ), dx9 ? SW_SHOW: SW_HIDE); ShowWindow(GetDlgItem(m_hWnd, IDC_FBA), dx9 ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE), ogl ? SW_SHOW : SW_HIDE); - ShowWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE_TEXT), ogl ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_BLEND_UNIT), ogl ? SW_SHOW : SW_HIDE); ShowWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_BLEND_UNIT_TEXT), ogl ? SW_SHOW : SW_HIDE); @@ -424,8 +422,8 @@ void GSSettingsDlg::UpdateControls() EnableWindow(GetDlgItem(m_hWnd, IDC_AFCOMBO), hw && filter && (ogl || !IsDlgButtonChecked(m_hWnd, IDC_PALTEX))); EnableWindow(GetDlgItem(m_hWnd, IDC_AFCOMBO_TEXT), hw && filter && (ogl || !IsDlgButtonChecked(m_hWnd, IDC_PALTEX))); } - EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE), ogl && hw); - EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE_TEXT), ogl && hw); + EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE), hw); + EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_DATE_TEXT), hw); EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_BLEND_UNIT), ogl && hw); EnableWindow(GetDlgItem(m_hWnd, IDC_ACCURATE_BLEND_UNIT_TEXT), ogl && hw);