GSDX: New interpretation of destination alpha testing to improve effect rendering as an optional hack. Known to make shadows in the persona games (and thus probably shin megami tensei) better, not sure what else it accomplishes without destroying other effects.

Now, a note about the actual issue.  Destination alpha tests can be used on the GS as one of the workarounds for a lack of stencils.  If you use a destination alpha test and leave alpha writing on, the GS will only write each pixel until you write an alpha value which would fail the test.  This works to a point in gsdx without further hacking, but that point is when within a single batch of primitives the same pixels are written multiple times and the destination alpha test is expected to update.  I did experimentally make a tight loop updating the stencil with a draw then drawing for one primitive at a time, but it was prohibitively slow (over 80% fps loss, you really don't want to know).

Destination alpha testing cannot be directly implemented in D3D9 or D3D10, but (probably) can in D3D11 (with a speed hit for sure, but I doubt it'll be 80%).  I'll be getting a new graphics card and looking into that.

And before some idiot says it, the answer is no.  OpenGL does not help.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@5346 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1@gmail.com 2012-07-24 02:20:07 +00:00
parent 96c8c13ead
commit 5f28d08286
9 changed files with 47 additions and 26 deletions

View File

@ -215,12 +215,13 @@ public:
uint32 zwe:1;
uint32 date:1;
uint32 fba:1;
uint32 alpha_stencil:1;
};
uint32 key;
};
operator uint32() {return key & 0x1f;}
operator uint32() {return key & 0x3f;}
OMDepthStencilSelector() : key(0) {}
};

View File

@ -32,6 +32,7 @@ GSRendererDX::GSRendererDX(GSTextureCache* tc, const GSVector2& pixelcenter)
UserHacks_AlphaHack = !!theApp.GetConfig("UserHacks_AlphaHack", 0) && !!theApp.GetConfig("UserHacks", 0);
UserHacks_WildHack = !!theApp.GetConfig("UserHacks", 0) ? theApp.GetConfig("UserHacks_WildHack", 0) : 0;
UserHacks_AlphaStencil = !!theApp.GetConfig("UserHacks_AlphaStencil", 0) && !!theApp.GetConfig("UserHacks", 0);
}
GSRendererDX::~GSRendererDX()
@ -259,6 +260,24 @@ void GSRendererDX::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sourc
if (context->TEST.ATE && context->TEST.ATST > 1)
ps_cb.FogColor_AREF.a = (float)context->TEST.AREF;
// Destination alpha pseudo stencil hack: use a stencil operation combined with an alpha test
// to only draw pixels which would cause the destination alpha test to fail in the future once.
// Unfortunately this also means only drawing those pixels at all, which is why this is a hack.
// The interaction with FBA in D3D9 is probably less than ideal.
if (UserHacks_AlphaStencil && DATE && dev->HasStencil() && om_bsel.wa && (!context->TEST.ATE || context->TEST.ATST == 1))
{
if (!context->FBA.FBA)
{
if (context->TEST.DATM == 0)
ps_sel.atst = 5; // >=
else
ps_sel.atst = 2; // <
ps_cb.FogColor_AREF.a = (float)0x80;
}
if (!(context->FBA.FBA && context->TEST.DATM == 1))
om_dssel.alpha_stencil = 1;
}
if(tex)
{
const GSLocalMemory::psm_t &psm = GSLocalMemory::m_psm[context->TEX0.PSM];

View File

@ -30,6 +30,7 @@ class GSRendererDX : public GSRendererHW
bool m_fba;
bool UserHacks_AlphaHack;
bool UserHacks_AlphaStencil;
protected:
virtual void DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Source* tex);

View File

@ -101,7 +101,6 @@ void GSSettingsDlg::OnInit()
CheckDlgButton(m_hWnd, IDC_WINDOWED, theApp.GetConfig("windowed", 1));
CheckDlgButton(m_hWnd, IDC_FILTER, theApp.GetConfig("filter", 2));
CheckDlgButton(m_hWnd, IDC_PALTEX, theApp.GetConfig("paltex", 0));
CheckDlgButton(m_hWnd, IDC_VSYNC, theApp.GetConfig("vsync", 0));
CheckDlgButton(m_hWnd, IDC_LOGZ, theApp.GetConfig("logz", 1));
CheckDlgButton(m_hWnd, IDC_FBA, theApp.GetConfig("fba", 1));
CheckDlgButton(m_hWnd, IDC_AA1, theApp.GetConfig("aa1", 0));
@ -201,7 +200,6 @@ bool GSSettingsDlg::OnCommand(HWND hWnd, UINT id, UINT code)
theApp.SetConfig("filter", (int)IsDlgButtonChecked(m_hWnd, IDC_FILTER));
theApp.SetConfig("paltex", (int)IsDlgButtonChecked(m_hWnd, IDC_PALTEX));
theApp.SetConfig("vsync", (int)IsDlgButtonChecked(m_hWnd, IDC_VSYNC));
theApp.SetConfig("logz", (int)IsDlgButtonChecked(m_hWnd, IDC_LOGZ));
theApp.SetConfig("fba", (int)IsDlgButtonChecked(m_hWnd, IDC_FBA));
theApp.SetConfig("aa1", (int)IsDlgButtonChecked(m_hWnd, IDC_AA1));
@ -423,6 +421,7 @@ void GSHacksDlg::OnInit()
CheckDlgButton(m_hWnd, IDC_SPRITEHACK, theApp.GetConfig("UserHacks_SpriteHack", 0));
CheckDlgButton(m_hWnd, IDC_WILDHACK, theApp.GetConfig("UserHacks_WildHack", 0));
CheckDlgButton(m_hWnd, IDC_AGGRESSIVECRC, theApp.GetConfig("UserHacks_AggressiveCRC", 0));
CheckDlgButton(m_hWnd, IDC_ALPHASTENCIL, theApp.GetConfig("UserHacks_AlphaStencil", 0));
CheckDlgButton(m_hWnd, IDC_CHECK_DISABLE_ALL_HACKS, theApp.GetConfig("UserHacks_DisableCrcHacks", 0));
SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_SETRANGE, 0, MAKELPARAM(1000, 0));
@ -490,6 +489,11 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
"Only affects few games, removing some effects which might make the image sharper/clearer.\n"
"Affected games: FFX, FFX2, FFXII, GOW2, ICO, SoTC, SSX3.";
break;
case IDC_ALPHASTENCIL:
helpstr = "Extend stencil based emulation of destination alpha to perform stencil operations while drawing.\n\n"
"Improves many shadows which are normally overdrawn in parts, may affect other effects.\n"
"Will disable partial transparency in some games or even prevent drawing some elements altogether.";
break;
case IDC_CHECK_DISABLE_ALL_HACKS:
helpstr = "FOR TESTING ONLY!!\n\n"
"Disable all CRC hacks - will break many games. Overrides CrcHacksExclusion at gsdx.ini\n"
@ -522,6 +526,7 @@ bool GSHacksDlg::OnMessage(UINT message, WPARAM wParam, LPARAM lParam)
theApp.SetConfig("UserHacks_SkipDraw", (int)SendMessage(GetDlgItem(m_hWnd, IDC_SKIPDRAWHACK), UDM_GETPOS, 0, 0));
theApp.SetConfig("UserHacks_WildHack", (int)IsDlgButtonChecked(m_hWnd, IDC_WILDHACK));
theApp.SetConfig("UserHacks_AggressiveCRC", (int)IsDlgButtonChecked(m_hWnd, IDC_AGGRESSIVECRC));
theApp.SetConfig("UserHacks_AlphaStencil", (int)IsDlgButtonChecked(m_hWnd, IDC_ALPHASTENCIL));
theApp.SetConfig("UserHacks_DisableCrcHacks", (int)IsDlgButtonChecked(m_hWnd, IDC_CHECK_DISABLE_ALL_HACKS));
EndDialog(m_hWnd, id);
} break;

View File

@ -298,11 +298,11 @@ void GSDevice11::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uin
dsd.StencilReadMask = 1;
dsd.StencilWriteMask = 1;
dsd.FrontFace.StencilFunc = D3D11_COMPARISON_EQUAL;
dsd.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP;
dsd.FrontFace.StencilPassOp = dssel.alpha_stencil ? 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 = D3D11_STENCIL_OP_KEEP;
dsd.BackFace.StencilPassOp = dssel.alpha_stencil ? D3D11_STENCIL_OP_ZERO : D3D11_STENCIL_OP_KEEP;
dsd.BackFace.StencilFailOp = D3D11_STENCIL_OP_KEEP;
dsd.BackFace.StencilDepthFailOp = D3D11_STENCIL_OP_KEEP;
}

View File

@ -238,11 +238,11 @@ void GSDevice9::SetupOM(OMDepthStencilSelector dssel, OMBlendSelector bsel, uint
{
dss->StencilEnable = true;
dss->StencilReadMask = 1;
dss->StencilWriteMask = 2;
dss->StencilWriteMask = dssel.alpha_stencil ? 3 : 2;
dss->StencilFunc = dssel.date ? D3DCMP_EQUAL : D3DCMP_ALWAYS;
dss->StencilPassOp = dssel.fba ? D3DSTENCILOP_REPLACE : D3DSTENCILOP_KEEP;
dss->StencilFailOp = dssel.fba ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP;
dss->StencilDepthFailOp = dssel.fba ? D3DSTENCILOP_ZERO : D3DSTENCILOP_KEEP;
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->StencilDepthFailOp = D3DSTENCILOP_KEEP;
dss->StencilRef = 3;
}

View File

@ -94,7 +94,8 @@ BEGIN
CONTROL "WildArmsOffset",IDC_WILDHACK,"Button",BS_AUTO3STATE | WS_TABSTOP,14,105,64,10
LTEXT "TEXT_GOES_HERE",IDC_HACK_DESCRIPTION,92,20,209,145
CONTROL "Aggressive-CRC",IDC_AGGRESSIVECRC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,122,66,10
CONTROL "Disable CRCs",IDC_CHECK_DISABLE_ALL_HACKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,15,157,58,10
CONTROL "Alpha Stencil",IDC_ALPHASTENCIL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,139,66,10
CONTROL "Disable CRCs",IDC_CHECK_DISABLE_ALL_HACKS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,156,58,10
END
IDD_SHADEBOOST DIALOGEX 0, 0, 316, 129

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1250"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Version="9.00"
Name="GSdx"
ProjectGUID="{18E42F6F-3A62-41EE-B42F-79366C4F1E95}"
RootNamespace="GSdx"
@ -1700,6 +1700,14 @@
RelativePath=".\res\convert.fx"
>
</File>
<File
RelativePath=".\res\cs.fx"
>
</File>
<File
RelativePath=".\res\fxaa.fx"
>
</File>
<File
RelativePath=".\res\interlace.fx"
>

View File

@ -24,27 +24,19 @@
*/
#define IDC_NATIVERES 2001
#define IDC_VSYNC 2002
#define IDC_PALTEX 2003
#define IDC_LOGZ 2004
#define IDC_CHECK6 2005
#define IDC_CODECS 2006
#define IDC_RESOLUTION 2007
#define IDC_SHADER 2008
#define IDC_RESX_EDIT 2009
#define IDC_RESY_EDIT 2010
#define IDC_AA1 2011
#define IDC_SWTHREADS_EDIT 2012
#define IDC_CUSTOM1 2013
#define IDC_MSAAEDIT 2013
#define IDC_CHECK4 2014
#define IDC_FILTER 2015
#define IDC_DITHERING 2016
#define IDC_RADIO1 2017
#define IDC_RESX 2018
#define IDC_RESY 2019
#define IDD_CONFIG 2020
#define IDC_MSAA 2020
#define IDB_LOGO9 2021
#define IDB_LOGO10 2022
#define IDC_FBA 2023
@ -52,7 +44,6 @@
#define IDC_LOGO11 2025
#define IDD_CAPTURE 2026
#define IDD_GPUCONFIG 2027
#define IDC_BLUR 2028
#define IDC_RENDERER 2029
#define IDC_INTERLACE 2030
#define IDC_ASPECTRATIO 2031
@ -67,14 +58,8 @@
#define IDC_WIDTH 2040
#define IDC_HEIGHT 2041
#define IDC_CONFIGURE 2042
#define IDC_STATIC_TEXT_HWAA 2043
#define IDC_ALPHAHACK2 2044
#define IDC_STATIC_TEXT_SKIPDRAW 2045
#define IDC_WINDOWED 2046
#define IDC_USERHACKS 2047
#define IDC_SKIPDRAWHACKEDIT 2048
#define IDC_STATIC10 2049
#define IDC_HACKDISABLED 2050
#define IDC_SPRITEHACK 2051
#define IDRESET 2052
#define IDC_SATURATION_SLIDER 2053
@ -94,6 +79,7 @@
#define IDC_STATIC_SKIPDRAW 2075
#define IDC_AGGRESSIVECRC 2076
#define IDC_CHECK_DISABLE_ALL_HACKS 2077
#define IDC_ALPHASTENCIL 2078
#define IDC_COLORSPACE 3000
#define IDR_CONVERT_FX 10000
#define IDR_TFX_FX 10001