From 489282969e01820da10abbb884d0fa2b0e874f42 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sat, 22 Mar 2025 23:21:11 +0000 Subject: [PATCH] GS/HW: More RT in RT regression fixes/improvements --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 12 ++++++------ pcsx2/GS/Renderers/HW/GSTextureCache.cpp | 15 ++++++++------- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index 267fae4870..2a13a44964 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -2494,6 +2494,8 @@ void GSRendererHW::Draw() return; } + m_process_texture = PRIM->TME && !(PRIM->ABE && m_context->ALPHA.IsBlack() && !m_cached_ctx.TEX0.TCC) && !(no_rt && (!m_cached_ctx.TEST.ATE || m_cached_ctx.TEST.ATST <= ATST_ALWAYS)); + // We trigger the sw prim render here super early, to avoid creating superfluous render targets. if (CanUseSwPrimRender(no_rt, no_ds, draw_sprite_tex && m_process_texture) && SwPrimRender(*this, true, true)) { @@ -2511,8 +2513,6 @@ void GSRendererHW::Draw() DetectRedundantBufferClear(no_rt, no_ds, fm_mask); } - m_process_texture = PRIM->TME && !(PRIM->ABE && m_context->ALPHA.IsBlack() && !m_cached_ctx.TEX0.TCC) && !(no_rt && (!m_cached_ctx.TEST.ATE || m_cached_ctx.TEST.ATST <= ATST_ALWAYS)); - CalculatePrimitiveCoversWithoutGaps(); const bool not_writing_to_all = (m_primitive_covers_without_gaps != NoGapsType::FullCover || AreAnyPixelsDiscarded() || !all_depth_tests_pass); @@ -6321,7 +6321,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c { src_target = tex->m_from_target; } - else if (!m_downscale_source) + else if (!m_downscale_source || !tex->m_from_target) { // No match. return; @@ -6335,7 +6335,7 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c GSVector4i copy_range; GSVector2i copy_size; GSVector2i copy_dst_offset; - bool copied_rt = false; + const bool copied_rt = src_target && !tex->m_shared_texture; // Shuffles take the whole target. This should've already been halved. // We can't partially copy depth targets in DirectX, and GL/Vulkan should use the direct read above. // Restricting it also breaks Tom and Jerry... @@ -6347,8 +6347,8 @@ __ri void GSRendererHW::HandleTextureHazards(const GSTextureCache::Target* rt, c copy_size.x = rt->m_unscaled_size.x; copy_size.y = rt->m_unscaled_size.y; copy_range.x = copy_range.y = 0; - copy_range.z = std::min(m_r.width(), copy_size.x); - copy_range.w = std::min(m_r.height(), copy_size.y); + copy_range.z = std::min(m_r.width() + 1, copy_size.x); + copy_range.w = std::min(m_r.height() + 1, copy_size.y); } else { diff --git a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp index 21fb7a9ef6..88815d4200 100644 --- a/pcsx2/GS/Renderers/HW/GSTextureCache.cpp +++ b/pcsx2/GS/Renderers/HW/GSTextureCache.cpp @@ -5506,13 +5506,7 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con src->m_shared_texture = true; src->m_32_bits_fmt = dst->m_32_bits_fmt; - // kill source immediately if it's the RT/DS, because that'll get invalidated immediately - if (GSRendererHW::GetInstance()->IsTBPFrameOrZ(dst->m_TEX0.TBP0) || channel_shuffle) - { - GL_CACHE("TC: Source is RT or ZBUF, invalidating after draw."); - m_temporary_source = src; - } - else if (new_size != dst_texture_size) + if (new_size != dst_texture_size) { // if the size doesn't match, we need to engage shader sampling. GL_CACHE("TC: Sample reduced region directly from target: %dx%d -> %dx%d", dst_texture_size.x, @@ -5523,6 +5517,13 @@ GSTextureCache::Source* GSTextureCache::CreateSource(const GIFRegTEX0& TEX0, con if (new_size.y != dst_texture_size.y) src->m_region.SetY(region_rect.y, region_rect.w); } + + // kill source immediately if it's the RT/DS, because that'll get invalidated immediately + if (GSRendererHW::GetInstance()->IsTBPFrameOrZ(dst->m_TEX0.TBP0) || channel_shuffle) + { + GL_CACHE("TC: Source is RT or ZBUF, invalidating after draw."); + m_temporary_source = src; + } } else {