From fbb1c7cb8e6a44bdf272d47028e190208c5a2d7f Mon Sep 17 00:00:00 2001 From: Stenzek Date: Fri, 28 Apr 2023 01:06:04 +1000 Subject: [PATCH] GS/OGL: Don't reuse targets when they're the texture I don't trust drivers to insert a barrier here. At least one of them gets it wrong. Also moves the masking of depth/colour to the common renderer for consistency. --- pcsx2/GS/Renderers/DX12/GSDevice12.cpp | 3 --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 4 ++++ pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp | 13 +++++-------- pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp | 3 --- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp index bfcb11c440..0e4d176592 100644 --- a/pcsx2/GS/Renderers/DX12/GSDevice12.cpp +++ b/pcsx2/GS/Renderers/DX12/GSDevice12.cpp @@ -3215,7 +3215,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) { draw_rt = m_current_render_target; m_pipeline_selector.rt = true; - m_pipeline_selector.cms.wrgba = 0; } } else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target && @@ -3223,8 +3222,6 @@ void GSDevice12::RenderHW(GSHWDrawConfig& config) { draw_ds = m_current_depth_target; m_pipeline_selector.ds = true; - m_pipeline_selector.dss.ztst = ZTST_ALWAYS; - m_pipeline_selector.dss.zwe = false; } OMSetRenderTargets(draw_rt, draw_ds, config.scissor); diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 5161888f1f..62ec593ddb 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -1524,6 +1524,7 @@ void GSRendererHW::Draw() GL_CACHE("Disabling Z buffer because all tests will pass."); m_cached_ctx.TEST.ZTST = ZTST_ALWAYS; + m_cached_ctx.ZBUF.ZMSK = true; } if (no_rt && no_ds) @@ -4319,7 +4320,10 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta // No point outputting colours if we're just writing depth. // We might still need the framebuffer for DATE, though. if (!rt || m_conf.colormask.wrgba == 0) + { m_conf.ps.DisableColorOutput(); + m_conf.colormask.wrgba = 0; + } if (m_conf.ps.scanmsk & 2) DATE_PRIMID = false; // to have discard in the shader work correctly diff --git a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp index 66d72b80ad..427f02b3c0 100644 --- a/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp +++ b/pcsx2/GS/Renderers/OpenGL/GSDeviceOGL.cpp @@ -2444,22 +2444,19 @@ void GSDeviceOGL::RenderHW(GSHWDrawConfig& config) // avoid changing framebuffer just to switch from rt+depth to rt and vice versa GSTexture* draw_rt = hdr_rt ? hdr_rt : config.rt; GSTexture* draw_ds = config.ds; - OMColorMaskSelector draw_colormask = config.colormask; - if (!draw_rt && GLState::rt && GLState::ds == draw_ds && GLState::rt->GetSize() == draw_ds->GetSize()) + if (!draw_rt && GLState::rt && GLState::ds == draw_ds && config.tex != GLState::rt && + GLState::rt->GetSize() == draw_ds->GetSize()) { draw_rt = GLState::rt; - draw_colormask.wrgba = 0; } - else if (!draw_ds && GLState::ds && GLState::rt == draw_rt && GLState::ds->GetSize() == draw_rt->GetSize()) + else if (!draw_ds && GLState::ds && GLState::rt == draw_rt && config.tex != GLState::ds && + GLState::ds->GetSize() == draw_rt->GetSize()) { - // should already be always-pass. draw_ds = GLState::ds; - config.depth.ztst = ZTST_ALWAYS; - config.depth.zwe = false; } OMSetRenderTargets(draw_rt, draw_ds, &config.scissor); - OMSetColorMaskState(draw_colormask); + OMSetColorMaskState(config.colormask); SetupOM(config.depth); SendHWDraw(config, psel.ps.IsFeedbackLoop()); diff --git a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp index 8aab86eac1..a676457bf7 100644 --- a/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp +++ b/pcsx2/GS/Renderers/Vulkan/GSDeviceVK.cpp @@ -3776,15 +3776,12 @@ void GSDeviceVK::RenderHW(GSHWDrawConfig& config) { draw_rt = m_current_render_target; m_pipeline_selector.rt = true; - m_pipeline_selector.cms.wrgba = 0; } else if (!draw_ds && m_current_depth_target && config.tex != m_current_depth_target && m_current_depth_target->GetSize() == draw_rt->GetSize()) { draw_ds = m_current_depth_target; m_pipeline_selector.ds = true; - m_pipeline_selector.dss.ztst = ZTST_ALWAYS; - m_pipeline_selector.dss.zwe = false; } // Prefer keeping feedback loop enabled, that way we're not constantly restarting render passes