GS/HW: Create new targets on shuffles when no target found

And get rid of some valid sizing thing which is just insane
This commit is contained in:
refractionpcsx2 2025-05-30 01:54:02 +01:00 committed by lightningterror
parent 284fba1ce3
commit cb7630a6ab
2 changed files with 47 additions and 4 deletions

View File

@ -4092,8 +4092,13 @@ void GSRendererHW::Draw()
const bool rt_update = can_update_size || (m_texture_shuffle && (src && rt && src->m_from_target != rt));
// If it's updating from a texture shuffle, limit the size to the source size.
if (rt_update && !can_update_size && src->m_from_target)
update_rect = update_rect.rintersect(src->m_from_target->m_valid);
if (rt_update && !can_update_size)
{
if(src->m_from_target)
update_rect = update_rect.rintersect(src->m_from_target->m_valid);
update_rect = update_rect.rintersect(GSVector4i::loadh(GSVector2i(new_w, new_h)));
}
// if frame is masked or afailing always to never write frame, wanna make sure we don't touch it. This might happen if DATE or Alpha Test is being used to write to Z.
const bool frame_masked = ((m_cached_ctx.FRAME.FBMSK & frame_psm.fmsk) == frame_psm.fmsk) || (m_cached_ctx.TEST.ATE && m_cached_ctx.TEST.ATST == ATST_NEVER && !(m_cached_ctx.TEST.AFAIL & AFAIL_FB_ONLY));

View File

@ -1988,6 +1988,8 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
src = CreateMergedSource(TEX0, TEXA, region, dst->m_scale);
}
GSVector4i rect = r;
if (!src)
{
#ifdef ENABLE_OGL_DEBUG
@ -2006,7 +2008,43 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
}
#endif
src = CreateSource(TEX0, TEXA, dst, x_offset, y_offset, lod, &r, gpu_clut, region);
// This is for the condition where the target doesn't exist on a shuffle and it needs to load from memory.
// The Godfather clears the depth buffer with a normal clear, so our depth target gets deleted, then because it finds no target
// it assumes it really is 16bits, causing the texture to be full of garbage, and our shuffle handling becomes a mess.
// In this case it's actually C24, but let's just assume it means C32, it shouldn't matter in this case.
GIFRegTEX0 src_TEX0 = TEX0;
if (possible_shuffle && !dst && psm_s.bpp == 16)
{
if (frame.FBW == src_TEX0.TBW && frame.FBW <= 14)
{
rect.y /= 2;
rect.w /= 2;
}
else
{
rect.x /= 2;
rect.z /= 2;
}
if (TEX0.TBP0 == frame.Block())
{
GIFRegTEX0 target_TEX0;
target_TEX0.TBP0 = frame.Block();
target_TEX0.PSM = PSMCT32;
target_TEX0.TBW = frame.FBW;
if (target_TEX0.TBW > 14)
target_TEX0.TBW /= 2;
dst = g_texture_cache->CreateTarget(target_TEX0, GSVector2i(rect.z, rect.w), GSVector2i(rect.z, rect.w), GSRendererHW::GetInstance()->GetUpscaleMultiplier(),
GSLocalMemory::m_psm[TEX0.PSM].depth ? DepthStencil : RenderTarget, true, 0, false, true, possible_shuffle, rect, nullptr);
}
else
{
src_TEX0.PSM = PSMCT32;
}
}
src = CreateSource(src_TEX0, TEXA, dst, x_offset, y_offset, lod, &rect, gpu_clut, region);
if (!src) [[unlikely]]
return nullptr;
}
@ -2071,7 +2109,7 @@ GSTextureCache::Source* GSTextureCache::LookupSource(const bool is_color, const
AttachPaletteToSource(src, psm_s.pal, true, true);
}
src->Update(r);
src->Update(rect);
return src;
}