From ee3b6e59eb2c4d4ec7730bfb2379c1f7e375ec08 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Wed, 27 Mar 2024 15:32:17 +1000 Subject: [PATCH] GS: Use SRC1_COLOR instead of SRC1_ALPHA for DSB Frees up the alpha channel of the second source for use with single pass afail. --- pcsx2/GS/Renderers/Common/GSDevice.cpp | 34 +++++++++++++------------- pcsx2/GS/Renderers/Common/GSDevice.h | 14 +++++++---- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 10 ++++---- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/pcsx2/GS/Renderers/Common/GSDevice.cpp b/pcsx2/GS/Renderers/Common/GSDevice.cpp index bd02221d3f..6a0b4a6745 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.cpp +++ b/pcsx2/GS/Renderers/Common/GSDevice.cpp @@ -871,9 +871,9 @@ const std::array GSDevice::m_blendMap = { BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0020: (Cs - Cs)*F + Cs ==> Cs { BLEND_CD , OP_ADD , CONST_ZERO , CONST_ONE} , // 0021: (Cs - Cs)*F + Cd ==> Cd { BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 0022: (Cs - Cs)*F + 0 ==> 0 - { BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , // 0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As - { BLEND_MIX1 , OP_ADD , SRC1_ALPHA , INV_SRC1_ALPHA} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) - { BLEND_MIX1 , OP_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As + { BLEND_A_MAX | BLEND_MIX2 , OP_SUBTRACT , CONST_ONE , SRC1_COLOR} , // 0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As + { BLEND_MIX1 , OP_ADD , SRC1_COLOR , INV_SRC1_COLOR} , // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) + { BLEND_MIX1 , OP_SUBTRACT , SRC1_COLOR , SRC1_COLOR} , // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As { BLEND_A_MAX , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , // 0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad { 0 , OP_ADD , DST_ALPHA , INV_DST_ALPHA} , // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) { 0 , OP_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad @@ -881,17 +881,17 @@ const std::array GSDevice::m_blendMap = { BLEND_MIX1 , OP_ADD , CONST_COLOR , INV_CONST_COLOR} , // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) { BLEND_MIX1 , OP_SUBTRACT , CONST_COLOR , CONST_COLOR} , // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F { BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) - { BLEND_ACCU , OP_ADD , SRC1_ALPHA , CONST_ONE} , // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd - { BLEND_NO_REC , OP_ADD , SRC1_ALPHA , CONST_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As + { BLEND_ACCU , OP_ADD , SRC1_COLOR , CONST_ONE} , // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd + { BLEND_NO_REC , OP_ADD , SRC1_COLOR , CONST_ZERO} , // 0202: (Cs - 0)*As + 0 ==> Cs*As { BLEND_A_MAX , OP_ADD , CONST_ONE , CONST_ZERO} , // 0210: (Cs - 0)*Ad + Cs ==> Cs*(Ad + 1) { BLEND_HW_CLR3 , OP_ADD , DST_ALPHA , CONST_ONE} , // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd { BLEND_HW_CLR3 , OP_ADD , DST_ALPHA , CONST_ZERO} , // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad { BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) { BLEND_ACCU , OP_ADD , CONST_COLOR , CONST_ONE} , // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd { BLEND_NO_REC , OP_ADD , CONST_COLOR , CONST_ZERO} , // 0222: (Cs - 0)*F + 0 ==> Cs*F - { BLEND_MIX3 , OP_ADD , INV_SRC1_ALPHA , SRC1_ALPHA} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) - { BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , // 1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As - { BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_ALPHA , SRC1_ALPHA} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As + { BLEND_MIX3 , OP_ADD , INV_SRC1_COLOR , SRC1_COLOR} , // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) + { BLEND_A_MAX | BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_COLOR , CONST_ONE} , // 1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As + { BLEND_MIX1 , OP_REV_SUBTRACT , SRC1_COLOR , SRC1_COLOR} , // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As { 0 , OP_ADD , INV_DST_ALPHA , DST_ALPHA} , // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) { BLEND_A_MAX , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , // 1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad { 0 , OP_REV_SUBTRACT , DST_ALPHA , DST_ALPHA} , // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad @@ -907,27 +907,27 @@ const std::array GSDevice::m_blendMap = { BLEND_NO_REC , OP_ADD , CONST_ONE , CONST_ZERO} , // 1120: (Cd - Cd)*F + Cs ==> Cs { BLEND_CD , OP_ADD , CONST_ZERO , CONST_ONE} , // 1121: (Cd - Cd)*F + Cd ==> Cd { BLEND_NO_REC , OP_ADD , CONST_ZERO , CONST_ZERO} , // 1122: (Cd - Cd)*F + 0 ==> 0 - { 0 , OP_ADD , CONST_ONE , SRC1_ALPHA} , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As - { BLEND_HW_CLR1 , OP_ADD , DST_COLOR , SRC1_ALPHA} , // 1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) - { BLEND_HW_CLR2 , OP_ADD , DST_COLOR , SRC1_ALPHA} , // 1202: (Cd - 0)*As + 0 ==> Cd*As + { 0 , OP_ADD , CONST_ONE , SRC1_COLOR} , // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As + { BLEND_HW_CLR1 , OP_ADD , DST_COLOR , SRC1_COLOR} , // 1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) + { BLEND_HW_CLR2 , OP_ADD , DST_COLOR , SRC1_COLOR} , // 1202: (Cd - 0)*As + 0 ==> Cd*As { 0 , OP_ADD , CONST_ONE , DST_ALPHA} , // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad { BLEND_HW_CLR1 , OP_ADD , DST_COLOR , DST_ALPHA} , // 1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) { 0 , OP_ADD , CONST_ZERO , DST_ALPHA} , // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad { 0 , OP_ADD , CONST_ONE , CONST_COLOR} , // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F { BLEND_HW_CLR1 , OP_ADD , DST_COLOR , CONST_COLOR} , // 1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) { BLEND_HW_CLR2 , OP_ADD , DST_COLOR , CONST_COLOR} , // 1222: (Cd - 0)*F + 0 ==> Cd*F - { BLEND_NO_REC , OP_ADD , INV_SRC1_ALPHA , CONST_ZERO} , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) - { BLEND_ACCU , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ONE} , // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As - { BLEND_NO_REC , OP_REV_SUBTRACT , SRC1_ALPHA , CONST_ZERO} , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As + { BLEND_NO_REC , OP_ADD , INV_SRC1_COLOR , CONST_ZERO} , // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) + { BLEND_ACCU , OP_REV_SUBTRACT , SRC1_COLOR , CONST_ONE} , // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As + { BLEND_NO_REC , OP_REV_SUBTRACT , SRC1_COLOR , CONST_ZERO} , // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As { 0 , OP_ADD , INV_DST_ALPHA , CONST_ZERO} , // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) { BLEND_HW_CLR3 , OP_REV_SUBTRACT , DST_ALPHA , CONST_ONE} , // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad { 0 , OP_REV_SUBTRACT , DST_ALPHA , CONST_ZERO} , // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad { BLEND_NO_REC , OP_ADD , INV_CONST_COLOR , CONST_ZERO} , // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) { BLEND_ACCU , OP_REV_SUBTRACT , CONST_COLOR , CONST_ONE} , // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F { BLEND_NO_REC , OP_REV_SUBTRACT , CONST_COLOR , CONST_ZERO} , // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F - { 0 , OP_SUBTRACT , CONST_ONE , SRC1_ALPHA} , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As - { 0 , OP_ADD , CONST_ZERO , INV_SRC1_ALPHA} , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) - { 0 , OP_SUBTRACT , CONST_ZERO , SRC1_ALPHA} , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As + { 0 , OP_SUBTRACT , CONST_ONE , SRC1_COLOR} , // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As + { 0 , OP_ADD , CONST_ZERO , INV_SRC1_COLOR} , // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) + { 0 , OP_SUBTRACT , CONST_ZERO , SRC1_COLOR} , // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As { 0 , OP_SUBTRACT , CONST_ONE , DST_ALPHA} , // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad { 0 , OP_ADD , CONST_ZERO , INV_DST_ALPHA} , // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) { 0 , OP_SUBTRACT , CONST_ZERO , DST_ALPHA} , // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad diff --git a/pcsx2/GS/Renderers/Common/GSDevice.h b/pcsx2/GS/Renderers/Common/GSDevice.h index 0c031ffe36..413bfea0ea 100644 --- a/pcsx2/GS/Renderers/Common/GSDevice.h +++ b/pcsx2/GS/Renderers/Common/GSDevice.h @@ -614,14 +614,17 @@ struct alignas(16) GSHWDrawConfig u8 enable : 1; u8 constant_enable : 1; u8 op : 6; - u8 src_factor; - u8 dst_factor; + u8 src_factor : 4; + u8 dst_factor : 4; + u8 src_alpha_factor : 4; + u8 dst_alpha_factor : 4; u8 constant; }; u32 key; }; BlendState(): key(0) {} - BlendState(bool enable_, u8 src_factor_, u8 dst_factor_, u8 op_, bool constant_enable_, u8 constant_) + BlendState(bool enable_, u8 src_factor_, u8 dst_factor_, u8 op_, + u8 src_alpha_factor_, u8 dst_alpha_factor_, bool constant_enable_, u8 constant_) : key(0) { enable = enable_; @@ -629,6 +632,8 @@ struct alignas(16) GSHWDrawConfig src_factor = src_factor_; dst_factor = dst_factor_; op = op_; + src_alpha_factor = src_alpha_factor_; + dst_alpha_factor = dst_alpha_factor_; constant = constant_; } }; @@ -955,8 +960,7 @@ public: __fi static constexpr bool IsDualSourceBlendFactor(u8 factor) { - return (factor == SRC1_ALPHA || factor == INV_SRC1_ALPHA || factor == SRC1_COLOR - /* || factor == INV_SRC1_COLOR*/); // not used + return (factor == SRC1_ALPHA || factor == INV_SRC1_ALPHA || factor == SRC1_COLOR || factor == INV_SRC1_COLOR); } __fi static constexpr bool IsConstantBlendFactor(u16 factor) { diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index f033d2f991..31fb04b6cf 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -4187,7 +4187,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT if (accumulation_blend) { // Keep HW blending to do the addition/subtraction - m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::CONST_ONE, blend.op, false, 0}; + m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::CONST_ONE, blend.op, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0}; // Remove Cd from sw blend, it's handled in hw if (m_conf.ps.blend_a == 1) @@ -4239,7 +4239,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT } // For mixed blend, the source blend is done in the shader (so we use CONST_ONE as a factor). - m_conf.blend = {true, GSDevice::CONST_ONE, blend.dst, blend.op, m_conf.ps.blend_c == 2, AFIX}; + m_conf.blend = {true, GSDevice::CONST_ONE, blend.dst, blend.op, GSDevice::CONST_ONE, GSDevice::CONST_ZERO,m_conf.ps.blend_c == 2, AFIX}; m_conf.ps.blend_mix = (blend.op == GSDevice::OP_REV_SUBTRACT) ? 2 : 1; // Elide DSB colour output if not used by dest. @@ -4252,7 +4252,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT // Replace Cs*Alpha + Cd*(1 - Alpha) with Cs*Alpha - Cd*(Alpha - 1). // Alpha - 1 subtraction is only done for the dual source output (hw blending part) since we are changing the equation. // Af will be replaced with As in shader and send it to dual source output. - m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::SRC1_COLOR, GSDevice::OP_SUBTRACT, false, 0}; + m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::SRC1_COLOR, GSDevice::OP_SUBTRACT, GSDevice::CONST_ONE, GSDevice::CONST_ZERO, false, 0}; // blend hw 1 will disable alpha clamp, we can reuse the old bits. m_conf.ps.blend_hw = 1; // DSB output will always be used. @@ -4272,7 +4272,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT { // Allow to compensate when Cs*(Alpha + 1) overflows, to compensate we change // the alpha output value for Cd*Alpha. - m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::SRC1_COLOR, blend.op, false, 0}; + m_conf.blend = {true, GSDevice::CONST_ONE, GSDevice::SRC1_COLOR, blend.op, GSDevice::CONST_ONE, GSDevice::CONST_ZERO,false, 0}; m_conf.ps.blend_hw = 3; m_conf.ps.no_color1 = false; @@ -4336,7 +4336,7 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT } const HWBlend blend = GSDevice::GetBlend(blend_index); - m_conf.blend = {true, blend.src, blend.dst, blend.op, m_conf.ps.blend_c == 2, AFIX}; + m_conf.blend = {true, blend.src, blend.dst, blend.op, GSDevice::CONST_ONE, GSDevice::CONST_ZERO,m_conf.ps.blend_c == 2, AFIX}; // Remove second color output when unused. Works around bugs in some drivers (e.g. Intel). m_conf.ps.no_color1 |= !GSDevice::IsDualSourceBlendFactor(m_conf.blend.src_factor) &&