diff --git a/bin/resources/shaders/dx11/tfx.fx b/bin/resources/shaders/dx11/tfx.fx index 9e55ef6c78..ef4c0450c0 100644 --- a/bin/resources/shaders/dx11/tfx.fx +++ b/bin/resources/shaders/dx11/tfx.fx @@ -848,11 +848,10 @@ void ps_blend(inout float4 Color, inout float4 As_rgba, float2 pos_xy) return; } - float4 RT = SW_BLEND_NEEDS_RT ? trunc(RtTexture.Load(int3(pos_xy, 0)) * 255.0f + 0.1f) : (float4)0.0f; + float4 RT = SW_BLEND_NEEDS_RT ? RtTexture.Load(int3(pos_xy, 0)) : (float4)0.0f; - float Ad = RT.a / 128.0f; - - float3 Cd = RT.rgb; + float Ad = PS_RTA_CORRECTION ? trunc(RT.a * 127.5f + 0.05f) / 128.0f : trunc(RT.a * 255.0f + 0.1f) / 128.0f; + float3 Cd = trunc(RT.rgb * 255.0f + 0.1f); float3 Cs = Color.rgb; float3 A = (PS_BLEND_A == 0) ? Cs : ((PS_BLEND_A == 1) ? Cd : (float3)0.0f); @@ -966,10 +965,10 @@ PS_OUTPUT ps_main(PS_INPUT input) C.a = 128.0f; } - float4 alpha_blend; + float4 alpha_blend = (float4)0.0f; if (SW_AD_TO_HW) { - float4 RT = trunc(RtTexture.Load(int3(input.p.xy, 0)) * 255.0f + 0.1f); + float4 RT = PS_RTA_CORRECTION ? trunc(RtTexture.Load(int3(input.p.xy, 0)) * 127.5f + 0.05f) : trunc(RtTexture.Load(int3(input.p.xy, 0)) * 255.0f + 0.1f); alpha_blend = (float4)(RT.a / 128.0f); } else diff --git a/bin/resources/shaders/opengl/tfx_fs.glsl b/bin/resources/shaders/opengl/tfx_fs.glsl index b5467e3679..5cafc59050 100644 --- a/bin/resources/shaders/opengl/tfx_fs.glsl +++ b/bin/resources/shaders/opengl/tfx_fs.glsl @@ -796,17 +796,20 @@ float As = As_rgba.a; #endif #if SW_BLEND_NEEDS_RT - vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f); + vec4 RT = fetch_rt(); #else // Not used, but we define it to make the selection below simpler. vec4 RT = vec4(0.0f); #endif - // FIXME FMT_16 case - // FIXME Ad or Ad * 2? - float Ad = RT.a / 128.0f; + + #if PS_RTA_CORRECTION + float Ad = trunc(RT.a * 127.5f + 0.05f) / 128.0f; + #else + float Ad = trunc(RT.a * 255.0f + 0.1f) / 128.0f; + #endif // Let the compiler do its jobs ! - vec3 Cd = RT.rgb; + vec3 Cd = trunc(RT.rgb * 255.0f + 0.1f); vec3 Cs = Color.rgb; #if PS_BLEND_A == 0 @@ -972,7 +975,12 @@ void ps_main() #endif #if SW_AD_TO_HW - vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f); + #if PS_RTA_CORRECTION + vec4 RT = trunc(fetch_rt() * 127.5f + 0.05f); + #else + vec4 RT = trunc(fetch_rt() * 255.0f + 0.1f); + #endif + vec4 alpha_blend = vec4(RT.a / 128.0f); #else vec4 alpha_blend = vec4(C.a / 128.0f); diff --git a/bin/resources/shaders/vulkan/tfx.glsl b/bin/resources/shaders/vulkan/tfx.glsl index a8463d0c14..1619e70d6c 100644 --- a/bin/resources/shaders/vulkan/tfx.glsl +++ b/bin/resources/shaders/vulkan/tfx.glsl @@ -1049,18 +1049,20 @@ void ps_blend(inout vec4 Color, inout vec4 As_rgba) #endif #if PS_FEEDBACK_LOOP_IS_NEEDED - vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f); + vec4 RT = sample_from_rt(); #else // Not used, but we define it to make the selection below simpler. vec4 RT = vec4(0.0f); #endif - // FIXME FMT_16 case - // FIXME Ad or Ad * 2? - float Ad = RT.a / 128.0f; + #if PS_RTA_CORRECTION + float Ad = trunc(RT.a * 127.5f + 0.05f) / 128.0f; + #else + float Ad = trunc(RT.a * 255.0f + 0.1f) / 128.0f; + #endif // Let the compiler do its jobs ! - vec3 Cd = RT.rgb; + vec3 Cd = trunc(RT.rgb * 255.0f + 0.1f); vec3 Cs = Color.rgb; #if PS_BLEND_A == 0 @@ -1223,8 +1225,13 @@ void main() C.a = 128.0f; #endif -#if (SW_AD_TO_HW) - vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f); +#if SW_AD_TO_HW + #if PS_RTA_CORRECTION + vec4 RT = trunc(sample_from_rt() * 127.5f + 0.05f); + #else + vec4 RT = trunc(sample_from_rt() * 255.0f + 0.1f); + #endif + vec4 alpha_blend = vec4(RT.a / 128.0f); #else vec4 alpha_blend = vec4(C.a / 128.0f); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 2d3da3764c..ff34fff158 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -4302,12 +4302,12 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, bool& DAT m_conf.ps.blend_d = 0; // TODO: Make it work on DATE, switch to new shaders with Ad doubled. - const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || rt_alpha_max > 128; + const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || rt_alpha_max > 128 || m_conf.ps.fbmask || m_conf.ps.tex_is_fb; const bool rta_correction = !rta_decorrection && !m_cached_ctx.TEST.DATE && !blend_ad_alpha_masked && m_conf.ps.blend_c == 1 && !(blend_flag & BLEND_A_MAX); if (rta_correction) { rt->RTACorrect(rt); - m_conf.ps.rta_correction = rt->m_rt_alpha_scale && m_conf.colormask.wa; + m_conf.ps.rta_correction = rt->m_rt_alpha_scale; m_conf.rt = rt->m_texture; } @@ -5303,15 +5303,17 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta } } + if (rt) { - const bool rta_decorrection = m_cached_ctx.TEST.DATE || m_channel_shuffle || m_texture_shuffle || blend_alpha_max > 128; - if (rt && rta_decorrection) + const bool rta_decorrection = m_channel_shuffle || m_texture_shuffle || std::max(blend_alpha_max, rt->m_alpha_max) > 128 || m_conf.ps.fbmask || m_conf.ps.tex_is_fb; + + if (rta_decorrection) { rt->RTADecorrect(rt); m_conf.rt = rt->m_texture; } - else if (rt) - m_conf.ps.rta_correction = rt->m_rt_alpha_scale && m_conf.colormask.wa; + + m_conf.ps.rta_correction = rt->m_rt_alpha_scale; } bool blending_alpha_pass = false; diff --git a/pcsx2/GS/Renderers/Metal/tfx.metal b/pcsx2/GS/Renderers/Metal/tfx.metal index 2e7041aded..cdd66e79aa 100644 --- a/pcsx2/GS/Renderers/Metal/tfx.metal +++ b/pcsx2/GS/Renderers/Metal/tfx.metal @@ -915,7 +915,7 @@ struct PSMain return; } - float Ad = trunc(current_color.a * 255.5f) / 128.f; + float Ad = PS_RTA_CORRECTION ? trunc(current_color.a * 127.75f) / 128.f : trunc(current_color.a * 255.5f) / 128.f; float3 Cd = trunc(current_color.rgb * 255.5f); float3 Cs = Color.rgb; @@ -1044,7 +1044,15 @@ struct PSMain C.a = 128.0f; } - float4 alpha_blend = SW_AD_TO_HW ? float4(trunc(current_color.a * 255.5f) / 128.f) : float4(C.a / 128.f); + float4 alpha_blend = float4(0.f); + if (SW_AD_TO_HW) + { + alpha_blend = PS_RTA_CORRECTION ? float4(trunc(current_color.a * 127.75f) / 128.f) : float4(trunc(current_color.a * 255.5f) / 128.f); + } + else + { + alpha_blend = float4(C.a / 128.f); + } if (PS_DST_FMT == FMT_16) {