GS/HW: Backport target expansion change from RT in RT PR

This commit is contained in:
refractionpcsx2 2025-01-12 06:55:12 +00:00 committed by lightningterror
parent 05917796a5
commit 68823c524f
4 changed files with 22 additions and 13 deletions

View File

@ -952,11 +952,11 @@ GSVector2i GSRendererHW::GetValidSize(const GSTextureCache::Source* tex)
return GSVector2i(width, height); return GSVector2i(width, height);
} }
GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex) GSVector2i GSRendererHW::GetTargetSize(const GSTextureCache::Source* tex, const bool can_expand)
{ {
const GSVector2i valid_size = GetValidSize(tex); const GSVector2i valid_size = GetValidSize(tex);
return g_texture_cache->GetTargetSize(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, valid_size.x, valid_size.y); return g_texture_cache->GetTargetSize(m_cached_ctx.FRAME.Block(), m_cached_ctx.FRAME.FBW, m_cached_ctx.FRAME.PSM, valid_size.x, valid_size.y, can_expand);
} }
bool GSRendererHW::IsPossibleChannelShuffle() const bool GSRendererHW::IsPossibleChannelShuffle() const
@ -2612,8 +2612,14 @@ void GSRendererHW::Draw()
} }
} }
// Urban Reign trolls by scissoring a draw to a target at 0x0-0x117F to 378x449 which ends up the size being rounded up to 640x480
// causing the buffer to expand to around 0x1400, which makes a later framebuffer at 0x1180 to fail to be created correctly.
// We can cheese this by checking if the Z is masked and the resultant colour is going to be black anyway.
const bool output_black = PRIM->ABE && ((m_context->ALPHA.A == 1 && m_context->ALPHA.B == 0 && GetAlphaMinMax().min >= 128) || m_context->ALPHA.IsBlack()) && m_draw_env->COLCLAMP.CLAMP == 1;
const bool can_expand = !(m_cached_ctx.ZBUF.ZMSK && output_black);
// Estimate size based on the scissor rectangle and height cache. // Estimate size based on the scissor rectangle and height cache.
const GSVector2i t_size = GetTargetSize(src); const GSVector2i t_size = GetTargetSize(src, can_expand);
const GSVector4i t_size_rect = GSVector4i::loadh(t_size); const GSVector4i t_size_rect = GSVector4i::loadh(t_size);
// Ensure draw rect is clamped to framebuffer size. Necessary for updating valid area. // Ensure draw rect is clamped to framebuffer size. Necessary for updating valid area.

View File

@ -214,7 +214,7 @@ public:
void MergeSprite(GSTextureCache::Source* tex); void MergeSprite(GSTextureCache::Source* tex);
float GetTextureScaleFactor() override; float GetTextureScaleFactor() override;
GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr); GSVector2i GetValidSize(const GSTextureCache::Source* tex = nullptr);
GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr); GSVector2i GetTargetSize(const GSTextureCache::Source* tex = nullptr, const bool can_expand = true);
void Reset(bool hardware_reset) override; void Reset(bool hardware_reset) override;
void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override; void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override;

View File

@ -4204,7 +4204,7 @@ GSTextureCache::Target* GSTextureCache::FindOverlappingTarget(u32 BP, u32 BW, u3
return FindOverlappingTarget(BP, end_bp); return FindOverlappingTarget(BP, end_bp);
} }
GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height) GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height, bool can_expand)
{ {
TargetHeightElem search = {}; TargetHeightElem search = {};
search.bp = bp; search.bp = bp;
@ -4218,14 +4218,17 @@ GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width
TargetHeightElem& elem = const_cast<TargetHeightElem&>(*it); TargetHeightElem& elem = const_cast<TargetHeightElem&>(*it);
if (elem.bits == search.bits) if (elem.bits == search.bits)
{ {
if (elem.width < min_width || elem.height < min_height) if (can_expand)
{ {
DbgCon.WriteLn("Expand size at %x %u %u from %ux%u to %ux%u", bp, fbw, psm, elem.width, elem.height, if (elem.width < min_width || elem.height < min_height)
min_width, min_height); {
} DbgCon.WriteLn("Expand size at %x %u %u from %ux%u to %ux%u", bp, fbw, psm, elem.width, elem.height,
min_width, min_height);
}
elem.width = std::max(elem.width, min_width); elem.width = std::max(elem.width, min_width);
elem.height = std::max(elem.height, min_height); elem.height = std::max(elem.height, min_height);
}
m_target_heights.MoveFront(it.Index()); m_target_heights.MoveFront(it.Index());
elem.age = 0; elem.age = 0;
@ -4233,7 +4236,7 @@ GSVector2i GSTextureCache::GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width
} }
} }
DbgCon.WriteLn("New size at %x %u %u: %ux%u", bp, fbw, psm, min_width, min_height); DbgCon.WriteLn("New size at %x %u %u: %ux%u draw %d", bp, fbw, psm, min_width, min_height, GSState::s_n);
m_target_heights.push_front(search); m_target_heights.push_front(search);
return GSVector2i(min_width, min_height); return GSVector2i(min_width, min_height);
} }

View File

@ -504,7 +504,7 @@ public:
Target* FindOverlappingTarget(u32 BP, u32 end_bp) const; Target* FindOverlappingTarget(u32 BP, u32 end_bp) const;
Target* FindOverlappingTarget(u32 BP, u32 BW, u32 PSM, GSVector4i rc) const; Target* FindOverlappingTarget(u32 BP, u32 BW, u32 PSM, GSVector4i rc) const;
GSVector2i GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height); GSVector2i GetTargetSize(u32 bp, u32 fbw, u32 psm, s32 min_width, s32 min_height, bool can_expand = true);
bool HasTargetInHeightCache(u32 bp, u32 fbw, u32 psm, u32 max_age = std::numeric_limits<u32>::max(), bool move_front = true); bool HasTargetInHeightCache(u32 bp, u32 fbw, u32 psm, u32 max_age = std::numeric_limits<u32>::max(), bool move_front = true);
bool Has32BitTarget(u32 bp); bool Has32BitTarget(u32 bp);