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", ""),
};
m_gs_acc_blend_level.push_back(GSSetting(0, "Minimum", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(1, "Basic", "Recommended"));
m_gs_acc_blend_level.push_back(GSSetting(2, "Medium", ""));
m_gs_acc_blend_level.push_back(GSSetting(3, "High", ""));
m_gs_acc_blend_level.push_back(GSSetting(4, "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::None), "Minimum", "Fastest"));
m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Basic), "Basic", "Recommended"));
m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Medium), "Medium", ""));
m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::High), "High", ""));
m_gs_acc_blend_level.push_back(GSSetting(static_cast<u32>(AccBlendLevel::Full), "Full", "Very 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(1, "Basic", "Recommended"));
m_gs_acc_blend_level_d3d11.push_back(GSSetting(2, "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::None), "Minimum", "Fastest"));
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(static_cast<u32>(AccBlendLevel::Medium), "Medium", "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(1, "Scanline filter", ""));

View File

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

View File

@ -18,7 +18,7 @@
GSRendererDX11::GSRendererDX11()
{
m_sw_blending = theApp.GetConfigI("accurate_blending_unit_d3d11");
m_sw_blending = static_cast<AccBlendLevel>(theApp.GetConfigI("accurate_blending_unit_d3d11"));
ResetStates();
}
@ -158,23 +158,23 @@ void GSRendererDX11::EmulateTextureShuffleAndFbmask()
bool enable_fbmask_emulation = false;
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).
// Debug
enable_fbmask_emulation = true;
break;
case ACC_BLEND_MEDIUM_D3D11:
case AccBlendLevel::Medium:
// Enable Fbmask emulation excluding triangle class because it is quite slow.
// 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));
break;
case ACC_BLEND_BASIC_D3D11:
case AccBlendLevel::Basic:
// Enable Fbmask emulation excluding triangle class because it is quite slow.
// 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.
enable_fbmask_emulation = (!m_texture_shuffle && (m_vt.m_primclass != GS_TRIANGLE_CLASS) && (m_context->FRAME.FBMSK != 0x80000000));
break;
case ACC_BLEND_NONE_D3D11:
case AccBlendLevel::None:
default:
break;
}
@ -473,9 +473,9 @@ void GSRendererDX11::EmulateBlending(u8& afix)
bool sw_blending = false;
switch (m_sw_blending)
{
case ACC_BLEND_HIGH_D3D11:
case ACC_BLEND_MEDIUM_D3D11:
case ACC_BLEND_BASIC_D3D11:
case AccBlendLevel::High:
case AccBlendLevel::Medium:
case AccBlendLevel::Basic:
sw_blending |= accumulation_blend || blend_non_recursive;
[[fallthrough]];
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
if (m_sw_blending)
if (m_sw_blending != AccBlendLevel::None)
{
blend_mix &= !sw_blending;
sw_blending |= blend_mix;

View File

@ -21,14 +21,6 @@
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:
bool m_bind_rtsample;

View File

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

View File

@ -19,7 +19,7 @@
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"))
UserHacks_tri_filter = static_cast<TriFiltering>(theApp.GetConfigI("UserHacks_TriFilter"));
else
@ -224,7 +224,7 @@ void GSRendererOGL::EmulateTextureShuffleAndFbmask()
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.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_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)
{
@ -507,30 +507,30 @@ void GSRendererOGL::EmulateBlending(bool& DATE_GL42, bool& DATE_GL45)
bool sw_blending = false;
switch (m_sw_blending)
{
case ACC_BLEND_ULTRA:
case AccBlendLevel::Ultra:
sw_blending |= true;
[[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));
[[fallthrough]];
case ACC_BLEND_HIGH:
case AccBlendLevel::High:
sw_blending |= (ALPHA.C == 1);
[[fallthrough]];
case ACC_BLEND_MEDIUM:
case AccBlendLevel::Medium:
// 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.
// 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;
[[fallthrough]];
case ACC_BLEND_BASIC:
case AccBlendLevel::Basic:
sw_blending |= impossible_or_free_blend;
[[fallthrough]];
default:
case AccBlendLevel::None:
/*sw_blending |= accumulation_blend*/;
}
// 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;
sw_blending |= blend_mix;
@ -1164,7 +1164,7 @@ void GSRendererOGL::DrawPrims(GSTexture* rt, GSTexture* ds, GSTextureCache::Sour
m_prim_overlap = PrimitiveOverlap();
// 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))
{
@ -1630,5 +1630,5 @@ bool GSRendererOGL::IsDummyTexture() const
{
// 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
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
};
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:
PRIM_OVERLAP m_prim_overlap;
std::vector<size_t> m_drawlist;