GS: Use shared enum for blend level

Even if DX11 doesn't support all modes we can just use the ones it does support from the enum
This commit is contained in:
TellowKrinkle 2021-12-10 17:11:50 -06:00 committed by lightningterror
parent ea98a1c9f9
commit b8984661d9
7 changed files with 42 additions and 50 deletions

View File

@ -1082,17 +1082,17 @@ void GSApp::Init()
GSSetting(CRCHackLevel::Aggressive, "Aggressive", ""), GSSetting(CRCHackLevel::Aggressive, "Aggressive", ""),
}; };
m_gs_acc_blend_level.push_back(GSSetting(0, "Minimum", "Fastest")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::None), "Minimum", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(1, "Basic", "Recommended")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Basic), "Basic", "Recommended"));
m_gs_acc_blend_level.push_back(GSSetting(2, "Medium", "")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Medium), "Medium", ""));
m_gs_acc_blend_level.push_back(GSSetting(3, "High", "")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::High), "High", ""));
m_gs_acc_blend_level.push_back(GSSetting(4, "Full", "Very Slow")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Full), "Full", "Very Slow"));
m_gs_acc_blend_level.push_back(GSSetting(5, "Ultra", "Ultra Slow")); m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Ultra), "Ultra", "Ultra Slow"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(0, "Minimum", "Fastest")); m_gs_acc_blend_level_d3d11.push_back(GSSetting(static_cast<u32>(AccBlendLevel::None), "Minimum", "Fastest"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(1, "Basic", "Recommended")); m_gs_acc_blend_level_d3d11.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Basic), "Basic", "Recommended"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(2, "Medium", "Debug")); m_gs_acc_blend_level_d3d11.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Medium), "Medium", "Debug"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(3, "High", "Debug")); m_gs_acc_blend_level_d3d11.push_back(GSSetting(static_cast<u32>(AccBlendLevel::High), "High", "Debug"));
m_gs_tv_shaders.push_back(GSSetting(0, "None", "")); m_gs_tv_shaders.push_back(GSSetting(0, "None", ""));
m_gs_tv_shaders.push_back(GSSetting(1, "Scanline filter", "")); m_gs_tv_shaders.push_back(GSSetting(1, "Scanline filter", ""));

View File

@ -98,6 +98,16 @@ enum class CRCHackLevel : s8
Aggressive Aggressive
}; };
enum class AccBlendLevel : u8
{
None,
Basic,
Medium,
High,
Full,
Ultra,
};
void GSsetBaseMem(u8* mem); void GSsetBaseMem(u8* mem);
int GSinit(); int GSinit();
void GSshutdown(); void GSshutdown();

View File

@ -18,7 +18,7 @@
GSRendererDX11::GSRendererDX11() GSRendererDX11::GSRendererDX11()
{ {
m_sw_blending = theApp.GetConfigI("accurate_blending_unit_d3d11"); m_sw_blending = static_cast<AccBlendLevel>(theApp.GetConfigI("accurate_blending_unit_d3d11"));
ResetStates(); ResetStates();
} }
@ -158,23 +158,23 @@ void GSRendererDX11::EmulateTextureShuffleAndFbmask()
bool enable_fbmask_emulation = false; bool enable_fbmask_emulation = false;
switch (m_sw_blending) switch (m_sw_blending)
{ {
case ACC_BLEND_HIGH_D3D11: case AccBlendLevel::High:
// Fully enable Fbmask emulation like on opengl, note misses sw blending to work as opengl on some games (Genji). // Fully enable Fbmask emulation like on opengl, note misses sw blending to work as opengl on some games (Genji).
// Debug // Debug
enable_fbmask_emulation = true; enable_fbmask_emulation = true;
break; break;
case ACC_BLEND_MEDIUM_D3D11: case AccBlendLevel::Medium:
// Enable Fbmask emulation excluding triangle class because it is quite slow. // Enable Fbmask emulation excluding triangle class because it is quite slow.
// Exclude 0x80000000 because Genji needs sw blending, otherwise it breaks some effects. // Exclude 0x80000000 because Genji needs sw blending, otherwise it breaks some effects.
enable_fbmask_emulation = ((m_vt.m_primclass != GS_TRIANGLE_CLASS) && (m_context->FRAME.FBMSK != 0x80000000)); enable_fbmask_emulation = ((m_vt.m_primclass != GS_TRIANGLE_CLASS) && (m_context->FRAME.FBMSK != 0x80000000));
break; break;
case ACC_BLEND_BASIC_D3D11: case AccBlendLevel::Basic:
// Enable Fbmask emulation excluding triangle class because it is quite slow. // Enable Fbmask emulation excluding triangle class because it is quite slow.
// Exclude 0x80000000 because Genji needs sw blending, otherwise it breaks some effects. // Exclude 0x80000000 because Genji needs sw blending, otherwise it breaks some effects.
// Also exclude fbmask emulation on texture shuffle just in case, it is probably safe tho. // Also exclude fbmask emulation on texture shuffle just in case, it is probably safe tho.
enable_fbmask_emulation = (!m_texture_shuffle && (m_vt.m_primclass != GS_TRIANGLE_CLASS) && (m_context->FRAME.FBMSK != 0x80000000)); enable_fbmask_emulation = (!m_texture_shuffle && (m_vt.m_primclass != GS_TRIANGLE_CLASS) && (m_context->FRAME.FBMSK != 0x80000000));
break; break;
case ACC_BLEND_NONE_D3D11: case AccBlendLevel::None:
default: default:
break; break;
} }
@ -473,9 +473,9 @@ void GSRendererDX11::EmulateBlending(u8& afix)
bool sw_blending = false; bool sw_blending = false;
switch (m_sw_blending) switch (m_sw_blending)
{ {
case ACC_BLEND_HIGH_D3D11: case AccBlendLevel::High:
case ACC_BLEND_MEDIUM_D3D11: case AccBlendLevel::Medium:
case ACC_BLEND_BASIC_D3D11: case AccBlendLevel::Basic:
sw_blending |= accumulation_blend || blend_non_recursive; sw_blending |= accumulation_blend || blend_non_recursive;
[[fallthrough]]; [[fallthrough]];
default: default:
@ -483,7 +483,7 @@ void GSRendererDX11::EmulateBlending(u8& afix)
} }
// Do not run BLEND MIX if sw blending is already present, it's less accurate // Do not run BLEND MIX if sw blending is already present, it's less accurate
if (m_sw_blending) if (m_sw_blending != AccBlendLevel::None)
{ {
blend_mix &= !sw_blending; blend_mix &= !sw_blending;
sw_blending |= blend_mix; sw_blending |= blend_mix;

View File

@ -21,14 +21,6 @@
class GSRendererDX11 final : public GSRendererHW class GSRendererDX11 final : public GSRendererHW
{ {
enum ACC_BLEND_D3D11
{
ACC_BLEND_NONE_D3D11 = 0,
ACC_BLEND_BASIC_D3D11 = 1,
ACC_BLEND_MEDIUM_D3D11 = 2,
ACC_BLEND_HIGH_D3D11 = 3
};
private: private:
bool m_bind_rtsample; bool m_bind_rtsample;

View File

@ -159,7 +159,7 @@ protected:
float m_userhacks_tcoffset_y; float m_userhacks_tcoffset_y;
bool m_accurate_date; bool m_accurate_date;
int m_sw_blending; AccBlendLevel m_sw_blending;
bool m_channel_shuffle; bool m_channel_shuffle;

View File

@ -19,7 +19,7 @@
GSRendererOGL::GSRendererOGL() GSRendererOGL::GSRendererOGL()
{ {
m_sw_blending = theApp.GetConfigI("accurate_blending_unit"); m_sw_blending = static_cast<AccBlendLevel>(theApp.GetConfigI("accurate_blending_unit"));
if (theApp.GetConfigB("UserHacks")) if (theApp.GetConfigB("UserHacks"))
UserHacks_tri_filter = static_cast<TriFiltering>(theApp.GetConfigI("UserHacks_TriFilter")); UserHacks_tri_filter = static_cast<TriFiltering>(theApp.GetConfigI("UserHacks_TriFilter"));
else else
@ -224,7 +224,7 @@ void GSRendererOGL::EmulateTextureShuffleAndFbmask()
m_ps_sel.fbmask = 1; m_ps_sel.fbmask = 1;
} }
if (m_ps_sel.fbmask && m_sw_blending) if (m_ps_sel.fbmask && m_sw_blending != AccBlendLevel::None)
{ {
ps_cb.FbMask.r = rg_mask; ps_cb.FbMask.r = rg_mask;
ps_cb.FbMask.g = rg_mask; ps_cb.FbMask.g = rg_mask;
@ -258,7 +258,7 @@ void GSRendererOGL::EmulateTextureShuffleAndFbmask()
m_om_csel.wrgba = ~ff_fbmask; // Enable channel if at least 1 bit is 0 m_om_csel.wrgba = ~ff_fbmask; // Enable channel if at least 1 bit is 0
m_ps_sel.fbmask = m_sw_blending && (~ff_fbmask & ~zero_fbmask & 0xF); m_ps_sel.fbmask = m_sw_blending != AccBlendLevel::None && (~ff_fbmask & ~zero_fbmask & 0xF);
if (m_ps_sel.fbmask) if (m_ps_sel.fbmask)
{ {
@ -507,30 +507,30 @@ void GSRendererOGL::EmulateBlending(bool& DATE_GL42, bool& DATE_GL45)
bool sw_blending = false; bool sw_blending = false;
switch (m_sw_blending) switch (m_sw_blending)
{ {
case ACC_BLEND_ULTRA: case AccBlendLevel::Ultra:
sw_blending |= true; sw_blending |= true;
[[fallthrough]]; [[fallthrough]];
case ACC_BLEND_FULL: case AccBlendLevel::Full:
sw_blending |= (ALPHA.A != ALPHA.B) && ((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u)); sw_blending |= (ALPHA.A != ALPHA.B) && ((ALPHA.C == 0 && m_vt.m_alpha.max > 128) || (ALPHA.C == 2 && ALPHA.FIX > 128u));
[[fallthrough]]; [[fallthrough]];
case ACC_BLEND_HIGH: case AccBlendLevel::High:
sw_blending |= (ALPHA.C == 1); sw_blending |= (ALPHA.C == 1);
[[fallthrough]]; [[fallthrough]];
case ACC_BLEND_MEDIUM: case AccBlendLevel::Medium:
// Initial idea was to enable accurate blending for sprite rendering to handle // Initial idea was to enable accurate blending for sprite rendering to handle
// correctly post-processing effect. Some games (ZoE) use tons of sprites as particles. // correctly post-processing effect. Some games (ZoE) use tons of sprites as particles.
// In order to keep it fast, let's limit it to smaller draw call. // In order to keep it fast, let's limit it to smaller draw call.
sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS && m_drawlist.size() < 100; sw_blending |= m_vt.m_primclass == GS_SPRITE_CLASS && m_drawlist.size() < 100;
[[fallthrough]]; [[fallthrough]];
case ACC_BLEND_BASIC: case AccBlendLevel::Basic:
sw_blending |= impossible_or_free_blend; sw_blending |= impossible_or_free_blend;
[[fallthrough]]; [[fallthrough]];
default: case AccBlendLevel::None:
/*sw_blending |= accumulation_blend*/; /*sw_blending |= accumulation_blend*/;
} }
// Do not run BLEND MIX if sw blending is already present, it's less accurate // Do not run BLEND MIX if sw blending is already present, it's less accurate
if (m_sw_blending) if (m_sw_blending != AccBlendLevel::None)
{ {
blend_mix &= !sw_blending; blend_mix &= !sw_blending;
sw_blending |= blend_mix; sw_blending |= blend_mix;
@ -1164,7 +1164,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
m_prim_overlap = PrimitiveOverlap(); m_prim_overlap = PrimitiveOverlap();
// Detect framebuffer read that will need special handling // Detect framebuffer read that will need special handling
if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && PRIM->TME && m_sw_blending) if ((m_context->FRAME.Block() == m_context->TEX0.TBP0) && PRIM->TME && m_sw_blending != AccBlendLevel::None)
{ {
if ((m_context->FRAME.FBMSK == 0x00FFFFFF) && (m_vt.m_primclass == GS_TRIANGLE_CLASS)) if ((m_context->FRAME.FBMSK == 0x00FFFFFF) && (m_vt.m_primclass == GS_TRIANGLE_CLASS))
{ {
@ -1630,5 +1630,5 @@ bool GSRendererOGL::IsDummyTexture() const
{ {
// Texture is actually the frame buffer. Stencil emulation to compute shadow (Jak series/tri-ace game) // Texture is actually the frame buffer. Stencil emulation to compute shadow (Jak series/tri-ace game)
// Will hit the "m_ps_sel.tex_is_fb = 1" path in the draw // Will hit the "m_ps_sel.tex_is_fb = 1" path in the draw
return (m_context->FRAME.Block() == m_context->TEX0.TBP0) && PRIM->TME && m_sw_blending && m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_context->FRAME.FBMSK == 0x00FFFFFF); return (m_context->FRAME.Block() == m_context->TEX0.TBP0) && PRIM->TME && m_sw_blending != AccBlendLevel::None && m_vt.m_primclass == GS_TRIANGLE_CLASS && (m_context->FRAME.FBMSK == 0x00FFFFFF);
} }

View File

@ -28,16 +28,6 @@ class GSRendererOGL final : public GSRendererHW
PRIM_OVERLAP_NO PRIM_OVERLAP_NO
}; };
enum ACC_BLEND
{
ACC_BLEND_NONE = 0,
ACC_BLEND_BASIC = 1,
ACC_BLEND_MEDIUM = 2,
ACC_BLEND_HIGH = 3,
ACC_BLEND_FULL = 4,
ACC_BLEND_ULTRA = 5
};
private: private:
PRIM_OVERLAP m_prim_overlap; PRIM_OVERLAP m_prim_overlap;
std::vector<size_t> m_drawlist; std::vector<size_t> m_drawlist;