From 7796b2a12b532af48dc600c3fa401fb4dfb2c535 Mon Sep 17 00:00:00 2001 From: lightningterror <18107717+lightningterror@users.noreply.github.com> Date: Wed, 21 May 2025 00:34:16 +0200 Subject: [PATCH] GS/HW: Add sanity/hazard checks for DATE and Texture barriers. When checking for full barrier, also check if texture barriers are supported. Get rid of preprocessSel in DX11, turn off full barrier and related stuff when not supported in rendererhw instead. Check if StencilDate types are actually enabled, don't want to turn it on for any others. --- pcsx2/GS/Renderers/DX11/GSDevice11.cpp | 17 +++-------------- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 13 +++++++++---- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp index 9500b5ce42..2480e810e9 100644 --- a/pcsx2/GS/Renderers/DX11/GSDevice11.cpp +++ b/pcsx2/GS/Renderers/DX11/GSDevice11.cpp @@ -2477,20 +2477,9 @@ D3D_SHADER_MACRO* GSDevice11::ShaderMacro::GetPtr() return (D3D_SHADER_MACRO*)mout.data(); } -/// Checks that we weren't sent things we declared we don't support -/// Clears things we don't support that can be quietly disabled -static void preprocessSel(GSDevice11::PSSelector& sel) -{ - pxAssert(sel.write_rg == 0); // Not supported, shouldn't be sent -} - void GSDevice11::RenderHW(GSHWDrawConfig& config) { - pxAssert(!config.require_full_barrier); // We always specify no support so it shouldn't request this - preprocessSel(config.ps); - - GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize(); - + const GSVector2i rtsize = (config.rt ? config.rt : config.ds)->GetSize(); GSTexture* colclip_rt = g_gs_device->GetColorClipTexture(); if (colclip_rt) @@ -2542,7 +2531,8 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) StretchRect(colclip_rt ? colclip_rt : config.rt, GSVector4(config.drawarea) / GSVector4(rtsize).xyxy(), primid_tex, GSVector4(config.drawarea), m_date.primid_init_ps[static_cast(config.datm)].get(), nullptr, false); } - else if (config.destination_alpha != GSHWDrawConfig::DestinationAlphaMode::Off) + else if (config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::Stencil || + config.destination_alpha == GSHWDrawConfig::DestinationAlphaMode::StencilOne) { const GSVector4 src = GSVector4(config.drawarea) / GSVector4(config.ds->GetSize()).xyxy(); const GSVector4 dst = src * 2.0f - 1.0f; @@ -2676,7 +2666,6 @@ void GSDevice11::RenderHW(GSHWDrawConfig& config) if (config.alpha_second_pass.enable) { - preprocessSel(config.alpha_second_pass.ps); if (config.cb_ps.FogColor_AREF.a != config.alpha_second_pass.ps_aref) { config.cb_ps.FogColor_AREF.a = config.alpha_second_pass.ps_aref; diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 3fd34b90b3..7e3d645e90 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -6054,10 +6054,9 @@ void GSRendererHW::EmulateBlending(int rt_alpha_min, int rt_alpha_max, const boo // Switch DATE_PRIMID with DATE_BARRIER in such cases to ensure accuracy. // No mix of COLCLIP + sw blend + DATE_PRIMID, neither sw fbmask + DATE_PRIMID. // Note: Do the swap in the end, saves the expensive draw splitting/barriers when mixed software blending is used. - if (sw_blending && DATE_PRIMID && m_conf.require_full_barrier) + if (sw_blending && DATE_PRIMID && features.texture_barrier && m_conf.require_full_barrier) { GL_PERF("DATE: Swap DATE_PRIMID with DATE_BARRIER"); - m_conf.require_full_barrier = true; DATE_PRIMID = false; DATE_BARRIER = true; } @@ -7472,7 +7471,7 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta if (m_conf.destination_alpha >= GSHWDrawConfig::DestinationAlphaMode::Stencil && m_conf.destination_alpha <= GSHWDrawConfig::DestinationAlphaMode::StencilOne && !m_conf.ds) { - const bool is_one_barrier = (m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle)); + const bool is_one_barrier = (features.texture_barrier && m_conf.require_full_barrier && (m_prim_overlap == PRIM_OVERLAP_NO || m_conf.ps.shuffle || m_channel_shuffle)); if ((temp_ds.reset(g_gs_device->CreateDepthStencil(m_conf.rt->GetWidth(), m_conf.rt->GetHeight(), GSTexture::Format::DepthStencil, false)), temp_ds)) { m_conf.ds = temp_ds.get(); @@ -7648,11 +7647,17 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta pxAssert(!m_conf.require_full_barrier || !m_conf.ps.colclip_hw); // 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)) + if (features.texture_barrier && 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; } + else if (!features.texture_barrier) + { + // These shouldn't be enabled if texture barriers aren't supported, make sure they are off. + m_conf.ps.write_rg = 0; + m_conf.require_full_barrier = false; + } // rs const GSVector4i hacked_scissor = m_channel_shuffle ? GSVector4i::cxpr(0, 0, 1024, 1024) : m_context->scissor.in;