From 59aba9f75732bc14c01ffecb33fee11f51e2ef35 Mon Sep 17 00:00:00 2001 From: lightningterror <18107717+lightningterror@users.noreply.github.com> Date: Thu, 9 Mar 2023 07:38:35 +0100 Subject: [PATCH] GS-hw: Support Ad masked alpha on blend mix 1 and 2 clr cases. --- bin/resources/shaders/dx11/tfx.fx | 4 ++-- bin/resources/shaders/opengl/tfx_fs.glsl | 4 ++-- bin/resources/shaders/vulkan/tfx.glsl | 4 ++-- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 8 +++++--- pcsx2/GS/Renderers/Metal/tfx.metal | 4 ++-- 5 files changed, 13 insertions(+), 11 deletions(-) diff --git a/bin/resources/shaders/dx11/tfx.fx b/bin/resources/shaders/dx11/tfx.fx index ef9159ded5..921cbf0b49 100644 --- a/bin/resources/shaders/dx11/tfx.fx +++ b/bin/resources/shaders/dx11/tfx.fx @@ -831,7 +831,7 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy) float3 alpha_compensate = max((float3)1.0f, Color.rgb / (float3)255.0f); As_rgba.rgb -= alpha_compensate; } - else if (PS_CLR_HW == 2) + else if (PS_CLR_HW == 2 || PS_CLR_HW == 4) { // Compensate slightly for Cd*(As + 1) - Cs*As. // The initial factor we chose is 1 (0.00392) @@ -841,7 +841,7 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy) float color_compensate = 1.0f * (C + 1.0f); Color.rgb -= (float3)color_compensate; } - else if (PS_CLR_HW == 3) + else if (PS_CLR_HW == 3 || PS_CLR_HW == 5) { // As, Ad or Af clamped. As_rgba.rgb = (float3)C_clamped; diff --git a/bin/resources/shaders/opengl/tfx_fs.glsl b/bin/resources/shaders/opengl/tfx_fs.glsl index 6293b1f986..f444622d4f 100644 --- a/bin/resources/shaders/opengl/tfx_fs.glsl +++ b/bin/resources/shaders/opengl/tfx_fs.glsl @@ -786,7 +786,7 @@ float As = As_rgba.a; // changed alpha should only be done for hw blend. vec3 alpha_compensate = max(vec3(1.0f), Color.rgb / vec3(255.0f)); As_rgba.rgb -= alpha_compensate; -#elif PS_CLR_HW == 2 +#elif PS_CLR_HW == 2 || PS_CLR_HW == 4 // Compensate slightly for Cd*(As + 1) - Cs*As. // The initial factor we chose is 1 (0.00392) // as that is the minimum color Cd can be, @@ -794,7 +794,7 @@ float As = As_rgba.a; // blended value it can be. float color_compensate = 1.0f * (C + 1.0f); Color.rgb -= vec3(color_compensate); -#elif PS_CLR_HW == 3 +#elif PS_CLR_HW == 3 || PS_CLR_HW == 5 // As, Ad or Af clamped. As_rgba.rgb = vec3(C_clamped); // Cs*(Alpha + 1) might overflow, if it does then adjust alpha value diff --git a/bin/resources/shaders/vulkan/tfx.glsl b/bin/resources/shaders/vulkan/tfx.glsl index d1df9ce5fd..97fd201fea 100644 --- a/bin/resources/shaders/vulkan/tfx.glsl +++ b/bin/resources/shaders/vulkan/tfx.glsl @@ -1105,7 +1105,7 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba) // changed alpha should only be done for hw blend. vec3 alpha_compensate = max(vec3(1.0f), Color.rgb / vec3(255.0f)); As_rgba.rgb -= alpha_compensate; - #elif PS_CLR_HW == 2 + #elif PS_CLR_HW == 2 || PS_CLR_HW == 4 // Compensate slightly for Cd*(As + 1) - Cs*As. // The initial factor we chose is 1 (0.00392) // as that is the minimum color Cd can be, @@ -1113,7 +1113,7 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba) // blended value it can be. float color_compensate = 1.0f * (C + 1.0f); Color.rgb -= vec3(color_compensate); - #elif PS_CLR_HW == 3 + #elif PS_CLR_HW == 3 || PS_CLR_HW == 5 // As, Ad or Af clamped. As_rgba.rgb = vec3(C_clamped); // Cs*(Alpha + 1) might overflow, if it does then adjust alpha value diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index bec264d197..f39fe652ed 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -3134,7 +3134,7 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool& { // Compensate slightly for Cd*(As + 1) - Cs*As. // Try to compensate a bit with subtracting 1 (0.00392) * (Alpha + 1) from Cs. - m_conf.ps.clr_hw = 2; + m_conf.ps.clr_hw = blend_ad_alpha_masked ? 4 : 2; } m_conf.ps.blend_a = 0; @@ -3146,7 +3146,7 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool& // 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.ps.clr_hw = 3; + m_conf.ps.clr_hw = blend_ad_alpha_masked ? 5 : 3; m_conf.ps.no_color1 = false; m_conf.ps.blend_a = 0; @@ -3165,7 +3165,9 @@ void GSRendererHW::EmulateBlending(bool& DATE_PRIMID, bool& DATE_BARRIER, bool& { m_conf.require_one_barrier |= true; // Swap Ad with As for hw blend - m_conf.ps.clr_hw = 6; + // Check if blend mix 1 or 2 already enabled clr + if (m_conf.ps.clr_hw == 0) + m_conf.ps.clr_hw = 6; } } else diff --git a/pcsx2/GS/Renderers/Metal/tfx.metal b/pcsx2/GS/Renderers/Metal/tfx.metal index 441b1e64ea..52ceb535d1 100644 --- a/pcsx2/GS/Renderers/Metal/tfx.metal +++ b/pcsx2/GS/Renderers/Metal/tfx.metal @@ -891,7 +891,7 @@ struct PSMain float3 alpha_compensate = max(float3(1.f), Color.rgb / float3(255.f)); As_rgba.rgb -= alpha_compensate; } - else if (PS_CLR_HW == 2) + else if (PS_CLR_HW == 2 || PS_CLR_HW == 4) { // Compensate slightly for Cd*(As + 1) - Cs*As. // The initial factor we chose is 1 (0.00392) @@ -901,7 +901,7 @@ struct PSMain float color_compensate = 1.f * (C + 1.f); Color.rgb -= float3(color_compensate); } - else if (PS_CLR_HW == 3) + else if (PS_CLR_HW == 3 || PS_CLR_HW == 5) { // As, Ad or Af clamped. As_rgba.rgb = float3(C_clamped);