mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-12-16 04:08:48 +00:00
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);
|
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.
|
// 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.
|
// 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 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);
|
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);
|
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
|
// The rectangle of the draw
|
||||||
m_r = GSVector4i(m_vt.m_min.p.xyxy(m_vt.m_max.p)).rintersect(GSVector4i(context->scissor.in));
|
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.TBP0 = context->FRAME.Block();
|
||||||
TEX0.TBW = context->FRAME.FBW;
|
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_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));
|
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)
|
if (rt)
|
||||||
{
|
{
|
||||||
pxAssert(rt->m_texture->GetScale() == up_s);
|
pxAssert(rt->m_texture->GetScale() == up_s);
|
||||||
|
|||||||
@ -186,7 +186,7 @@ public:
|
|||||||
void MergeSprite(GSTextureCache::Source* tex);
|
void MergeSprite(GSTextureCache::Source* tex);
|
||||||
GSVector2 GetTextureScaleFactor() override;
|
GSVector2 GetTextureScaleFactor() override;
|
||||||
GSVector2i GetOutputSize(int real_h);
|
GSVector2i GetOutputSize(int real_h);
|
||||||
GSVector2i GetTargetSize();
|
GSVector2i GetTargetSize(GSVector2i* unscaled_size = nullptr);
|
||||||
|
|
||||||
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;
|
||||||
|
|||||||
@ -2548,6 +2548,9 @@ void GSTextureCache::Target::UpdateValidity(const GSVector4i& rect)
|
|||||||
m_valid = m_valid.runion(rect);
|
m_valid = m_valid.runion(rect);
|
||||||
|
|
||||||
// Block of the bottom right texel of the validity rectangle, last valid block of the texture
|
// 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
|
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);
|
// 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
Block a user