GS/HW: Clear instead of invalidating upscaled targets

This'll require a little more VRAM bandwidth, but it's better than
sampling random garbage because HPO pushes the coordinates down.
This commit is contained in:
Stenzek 2024-06-26 12:34:55 +10:00 committed by Connor McLaughlin
parent 71cb2daea8
commit 7f0ab1442e
3 changed files with 24 additions and 12 deletions

View File

@ -6002,12 +6002,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
// FIXME D3D11 and GL support half pixel center. Code could be easier!!!
const GSTextureCache::Target* rt_or_ds = rt ? rt : ds;
const float rtscale = rt_or_ds ? rt_or_ds->GetScale() : 0.0f;
const GSVector2i rtsize = rt_or_ds ? rt_or_ds->GetTexture()->GetSize() : GSVector2i(0, 0);
const float rtscale = rt_or_ds->GetScale();
const GSVector2i rtsize = rt_or_ds->GetTexture()->GetSize();
float sx, sy, ox2, oy2;
const float ox = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFX));
const float oy = static_cast<float>(static_cast<int>(m_context->XYOFFSET.OFY));
if (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native && (!rt || rt->GetScale() > 1.0f))
if (GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native && rtscale > 1.0f)
{
sx = 2.0f * rtscale / (rtsize.x << 4);
sy = 2.0f * rtscale / (rtsize.y << 4);
@ -6032,12 +6032,12 @@ __ri void GSRendererHW::DrawPrims(GSTextureCache::Target* rt, GSTextureCache::Ta
else
{
// Align coordinates to native resolution framebuffer, hope for the best.
const int scaled_x = rt_or_ds ? rt_or_ds->GetUnscaledWidth() : 0;
const int scaled_y = rt_or_ds ? rt_or_ds->GetUnscaledHeight() : 0;
sx = 2.0f / (scaled_x << 4);
sy = 2.0f / (scaled_y << 4);
ox2 = -1.0f / scaled_x;
oy2 = -1.0f / scaled_y;
const int unscaled_x = rt_or_ds ? rt_or_ds->GetUnscaledWidth() : 0;
const int unscaled_y = rt_or_ds ? rt_or_ds->GetUnscaledHeight() : 0;
sx = 2.0f / (unscaled_x << 4);
sy = 2.0f / (unscaled_y << 4);
ox2 = -1.0f / unscaled_x;
oy2 = -1.0f / unscaled_y;
}
m_conf.cb_vs.vertex_scale = GSVector2(sx, sy);

View File

@ -2113,11 +2113,23 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
}
// And invalidate the target, we're drawing over it so we don't care what's there.
GL_INS("TC: Invalidating target %s[%x] because it's completely overwritten.", to_string(type), dst->m_TEX0.TBP0);
// We can't do this when upscaling, because of the vertex offset, the top/left rows often aren't drawn.
GL_INS("TC: Invalidating%s target %s[%x] because it's completely overwritten.", to_string(type),
(scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset == GSHalfPixelOffset::Native) ? "[clearing] " : "", dst->m_TEX0.TBP0);
if (scale > 1.0f && GSConfig.UserHacks_HalfPixelOffset != GSHalfPixelOffset::Native)
{
if (dst->m_type == RenderTarget)
g_gs_device->ClearRenderTarget(dst->m_texture, 0);
else
g_gs_device->ClearDepth(dst->m_texture, 0.0f);
}
else
{
g_gs_device->InvalidateRenderTarget(dst->m_texture);
}
}
}
}
else if (!is_frame && !GSConfig.UserHacks_DisableDepthSupport)
{
const int rev_type = (type == DepthStencil) ? RenderTarget : DepthStencil;

View File

@ -884,7 +884,7 @@ void Pcsx2Config::GSOptions::LoadSave(SettingsWrapper& wrap)
SettingsWrapEntryEx(UpscaleMultiplier, "upscale_multiplier");
// ~51x would the upper bound here for 32768x32768 textures, but you'll run out VRAM long before then.
UpscaleMultiplier = std::clamp(UpscaleMultiplier, 0.5f, 50.0f);
UpscaleMultiplier = std::clamp(UpscaleMultiplier, 1.0f, 50.0f);
SettingsWrapBitBoolEx(HWMipmap, "hw_mipmap");
SettingsWrapIntEnumEx(AccurateBlendingUnit, "accurate_blending_unit");