mirror of https://github.com/PCSX2/pcsx2.git
GS/HW: Clamp draw rect to unscaled, not scaled coordinates
Fixes broken shuffle effect in Haunting Ground when upscale is set above 1x.
This commit is contained in:
parent
60714b5ca4
commit
bcc4548f7b
|
@ -736,7 +736,7 @@ GSVector2 GSRendererHW::GetTextureScaleFactor()
|
|||
return GSVector2(f_upscale, f_upscale);
|
||||
}
|
||||
|
||||
GSVector2i GSRendererHW::GetTargetSize()
|
||||
GSVector2i GSRendererHW::GetTargetSize(GSVector2i* unscaled_size)
|
||||
{
|
||||
// Don't blindly expand out to the scissor size if we're not drawing to it.
|
||||
// e.g. Burnout 3, God of War II, etc.
|
||||
|
@ -761,6 +761,11 @@ GSVector2i GSRendererHW::GetTargetSize()
|
|||
|
||||
const u32 width = m_context->FRAME.FBW * 64u;
|
||||
const u32 height = m_tc->GetTargetHeight(m_context->FRAME.FBP, m_context->FRAME.FBW, m_context->FRAME.PSM, min_height);
|
||||
if (unscaled_size)
|
||||
{
|
||||
unscaled_size->x = static_cast<int>(width);
|
||||
unscaled_size->y = static_cast<int>(height);
|
||||
}
|
||||
|
||||
GL_INS("Target size for %x %u %u: %ux%u", m_context->FRAME.FBP, m_context->FRAME.FBW, m_context->FRAME.PSM, width, height);
|
||||
|
||||
|
@ -1581,7 +1586,11 @@ void GSRendererHW::Draw()
|
|||
|
||||
// The rectangle of the draw
|
||||
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
||||
const GSVector2i t_size = GetTargetSize();
|
||||
GSVector2i unscaled_size;
|
||||
const GSVector2i t_size = GetTargetSize(&unscaled_size);
|
||||
|
||||
// Ensure draw rect is clamped to framebuffer size. Necessary for updating valid area.
|
||||
m_r = m_r.rintersect(GSVector4i(0, 0, unscaled_size.x, unscaled_size.y));
|
||||
|
||||
TEX0.TBP0 = context->FRAME.Block();
|
||||
TEX0.TBW = context->FRAME.FBW;
|
||||
|
@ -1613,9 +1622,6 @@ void GSRendererHW::Draw()
|
|||
const int new_w = std::max(t_size.x, std::max(rt ? rt->m_texture->GetWidth() : 0, ds ? ds->m_texture->GetWidth() : 0));
|
||||
const int new_h = std::max(t_size.y, std::max(rt ? rt->m_texture->GetHeight() : 0, ds ? ds->m_texture->GetHeight() : 0));
|
||||
|
||||
// Ensure draw rect is clamped to framebuffer size. Necessary for updating valid area.
|
||||
m_r = m_r.rintersect(GSVector4i(0, 0, new_w, new_h));
|
||||
|
||||
if (rt)
|
||||
{
|
||||
pxAssert(rt->m_texture->GetScale() == up_s);
|
||||
|
|
|
@ -186,7 +186,7 @@ public:
|
|||
void MergeSprite(GSTextureCache::Source* tex);
|
||||
GSVector2 GetTextureScaleFactor() override;
|
||||
GSVector2i GetOutputSize(int real_h);
|
||||
GSVector2i GetTargetSize();
|
||||
GSVector2i GetTargetSize(GSVector2i* unscaled_size = nullptr);
|
||||
|
||||
void Reset(bool hardware_reset) override;
|
||||
void UpdateSettings(const Pcsx2Config::GSOptions& old_config) override;
|
||||
|
|
|
@ -2548,6 +2548,9 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect)
|
|||
m_valid = m_valid.runion(rect);
|
||||
|
||||
// Block of the bottom right texel of the validity rectangle, last valid block of the texture
|
||||
// TODO: This is not correct when the PSM changes. e.g. a 512x448 target being shuffled will become 512x896 temporarily, and
|
||||
// at the moment, we blow the valid rect out to twice the size. The only thing stopping everything breaking is the fact
|
||||
// that we clamp the draw rect to the target size in GSRendererHW::Draw().
|
||||
m_end_block = GSLocalMemory::m_psm[m_TEX0.PSM].info.bn(m_valid.z - 1, m_valid.w - 1, m_TEX0.TBP0, m_TEX0.TBW); // Valid only for color formats
|
||||
|
||||
// GL_CACHE("UpdateValidity (0x%x->0x%x) from R:%d,%d Valid: %d,%d", m_TEX0.TBP0, m_end_block, rect.z, rect.w, m_valid.z, m_valid.w);
|
||||
|
|
Loading…
Reference in New Issue