GSdx-d3d: Partial port for DATE one (Fast Date) and Fast Accurate Date.

It fixes a bunch of shadow/transparency issues.
Fast DATE doesn't rely on the gui option and is always on.
Confirmed fixed issues: Persona 3 shadows on d3d11,
Digital Devil Saga Transparency d3d9/11.

Fast accurate date works the same/similar to OpenGL.
Confirmed fixed issues: DBZ BT3 ground shadows, Fifa Street 1 shadows
on all d3d renders as well.

Also this option doesn't cause other transparency issues like the
Alpha Stencil hack.

Note: If Alpha Stencil is enabled Fast Date and Fast Accurate Date will
be disabled.

Note2: Full Accurate Date is not implemented so the code fallbacks to
Fast mode instead.

Commits:
3ab12cef2f
584397a3fd

This will probably be the last feature d3d9 gets before getting purged.
This commit is contained in:
lightningterror 2018-11-28 20:33:15 +01:00
parent b33418f270
commit 6c34f6c334
11 changed files with 65 additions and 17 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -247,7 +247,7 @@ public:
uint32 zwe:1;
uint32 date:1;
uint32 fba:1;
uint32 alpha_stencil:1;
uint32 date_one:1;
};
uint32 key;

View File

@ -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)

View File

@ -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");

View File

@ -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

View File

@ -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.

View File

@ -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<size_t> m_drawlist;

View File

@ -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"

View File

@ -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);