diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 2fc13148f1..0d3b5e7430 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -5015,10 +5015,8 @@ __ri bool GSRendererHW::EmulateChannelShuffle(GSTextureCache::Target* src, bool // Hitman suffers from this, not sure on the exact scenario at the moment, but we need the barrier. if (PRIM->ABE && m_context->ALPHA.IsCdInBlend()) { - if (m_prim_overlap == PRIM_OVERLAP_NO || !g_gs_device->Features().texture_barrier) - m_conf.require_one_barrier = true; - else - m_conf.require_full_barrier = true; + // Assume no overlap when it's a channel shuffle, no need for full barriers. + m_conf.require_one_barrier = true; } // This is for offsetting the texture, however if the texture has a region clamp, we don't want to move it. @@ -5287,9 +5285,10 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo const bool one_barrier = m_conf.require_one_barrier || blend_ad_alpha_masked; // Condition 1: Require full sw blend for full barrier. - // Condition 2: One barrier is already enabled, prims don't overlap so let's use sw blend instead. - // Condition 3: A shuffle is unlikely to overlap, so when a barrier is enabled like from fbmask we can prefer full sw blend. - const bool prefer_sw_blend = (features.texture_barrier && m_conf.require_full_barrier) || (m_conf.require_one_barrier && no_prim_overlap) || m_conf.ps.shuffle; + // Condition 2: One barrier is already enabled, prims don't overlap or is a channel shuffle so let's use sw blend instead. + // Condition 3: A texture shuffle is unlikely to overlap, so we can prefer full sw blend. + // Condition 4: If it's tex in fb draw and there's no overlap prefer sw blend, fb is already being read. + const bool prefer_sw_blend = (features.texture_barrier && m_conf.require_full_barrier) || (m_conf.require_one_barrier && (no_prim_overlap || m_channel_shuffle)) || m_conf.ps.shuffle || (no_prim_overlap && (m_conf.tex == m_conf.rt)); const bool free_blend = blend_non_recursive // Free sw blending, doesn't require barriers or reading fb || accumulation_blend; // Mix of hw/sw blending @@ -7440,8 +7439,8 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta // Multi-pass algorithms shouldn't be needed with full barrier and backends may not handle this correctly pxAssert(!m_conf.require_full_barrier || !m_conf.ps.colclip_hw); - // Swap full barrier for one barrier when there's no overlap, or a texture shuffle. - if (m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle)) + // Swap full barrier for one barrier when there's no overlap, or a shuffle. + if (m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle)) { m_conf.require_full_barrier = false; m_conf.require_one_barrier = true;