Skip to content

Commit

Permalink
GS/HW: Improve detection of upscaling and downscaling
Browse files Browse the repository at this point in the history
  • Loading branch information
refractionpcsx2 committed Jun 10, 2024
1 parent f2e3f25 commit 2a74cb8
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 13 deletions.
36 changes: 24 additions & 12 deletions pcsx2/GS/Renderers/HW/GSRendererHW.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7141,27 +7141,39 @@ int GSRendererHW::IsScalingDraw(GSTextureCache::Source* src, bool no_gaps)
if (GSConfig.UserHacks_NativeScaling == GSNativeScaling::Off)
return 0;

if (m_context->TEX1.MMAG != 1 || m_vt.m_primclass < GS_TRIANGLE_CLASS || m_cached_ctx.FRAME.Block() == m_cached_ctx.TEX0.TBP0 ||
IsMipMapDraw() || GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].trbpp <= 8 || !src || !src->m_from_target)
return 0;

const GSVector2i draw_size = GSVector2i(m_vt.m_max.p.x - m_vt.m_min.p.x, m_vt.m_max.p.y - m_vt.m_min.p.y);
const GSVector2i tex_size = GSVector2i(m_vt.m_max.t.x - m_vt.m_min.t.x, m_vt.m_max.t.y - m_vt.m_min.t.y);
// Check if we're already downscaled and drawing in current size, try not to rescale it.
if (src && src->m_from_target && (std::abs(draw_size.x - tex_size.x) <= 1 && std::abs(draw_size.y - tex_size.y) <= 1))
return -1;

// Try to detect if a game is downscaling/upscaling the image in order to do post processing/bloom effects.
const bool is_downscale = (tex_size.x / 2.0f) >= (draw_size.x - 1) && (tex_size.y / 2.0f) >= (draw_size.y - 1);
if (is_downscale && draw_size.x >= PCRTCDisplays.GetResolution().x)
// Try to catch cases of stupid draws like Manhunt and Syphon Filter where they sample a single pixel.
if(tex_size.x == 0 || tex_size.y == 0 || draw_size.x == 0 || draw_size.y == 0)
return 0;

const bool is_upscale = (draw_size.x / 2.0f) >= (tex_size.x - 1) && (draw_size.y / 2.0f) >= (tex_size.y - 1);
if (std::abs(draw_size.x - tex_size.x) <= 1 && std::abs(draw_size.y - tex_size.y) <= 1)
return -1;
//const bool is_downscale = (tex_size.x / 2.0f) >= (draw_size.x - 1) && (tex_size.y / 2.0f) >= (draw_size.y - 1);
// Should usually be 2x but some games like Monster House goes from 512x448 -> 128x128

const bool is_downscale = draw_size.x <= (tex_size.x - draw_size.x) || draw_size.y <= (tex_size.y - draw_size.y);

//if (is_downscale != is_downscale2)
// DevCon.Warning("Is down %d down2 is %d draw %d", is_downscale, is_downscale2, s_n);
if (is_downscale && draw_size.x >= PCRTCDisplays.GetResolution().x)
return 0;

const bool is_upscale = (draw_size.x / tex_size.x) >= 4 || (draw_size.y / tex_size.y) >= 4;
// DMC does a blit in strips with the scissor to keep it inside page boundaries, so that's not technically full coverage
// but good enough for what we want.
const bool no_gaps_or_single_sprite = (no_gaps || (m_vt.m_primclass == GS_SPRITE_CLASS && SpriteDrawWithoutGaps()));
if (no_gaps_or_single_sprite && m_vt.m_primclass >= GS_TRIANGLE_CLASS && m_context->TEX1.MMAG == 1 && src && src->m_from_target &&
GSLocalMemory::m_psm[m_cached_ctx.TEX0.PSM].trbpp > 8 && m_cached_ctx.FRAME.Block() != m_cached_ctx.TEX0.TBP0 && !IsMipMapDraw() &&
((is_upscale && !IsDiscardingDstColor()) || (((PRIM->ABE && m_context->ALPHA.C == 2 && m_context->ALPHA.FIX == 255) || IsDiscardingDstColor()) && is_downscale)))
const bool no_gaps_or_single_sprite = (is_downscale || is_upscale) && (no_gaps || (m_vt.m_primclass == GS_SPRITE_CLASS && SpriteDrawWithoutGaps()));

const bool dst_discarded = IsDiscardingDstColor();
if (no_gaps_or_single_sprite && ((is_upscale && !dst_discarded) ||
(is_downscale && (dst_discarded || (PRIM->ABE && m_context->ALPHA.C == 2 && m_context->ALPHA.FIX == 255)))))
{
GL_INS("%s draw detected - from %dx%d to %dx%d", is_downscale ? "Downscale" : "Upscale", tex_size.x, tex_size.y, draw_size.x, draw_size.y);
DevCon.Warning("%s draw detected - from %dx%d to %dx%d draw %d", is_downscale ? "Downscale" : "Upscale", tex_size.x, tex_size.y, draw_size.x, draw_size.y, s_n);
return is_upscale ? 2 : 1;
}

Expand Down
2 changes: 1 addition & 1 deletion pcsx2/GS/Renderers/HW/GSTextureCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1984,7 +1984,7 @@ GSTextureCache::Target* GSTextureCache::LookupTarget(GIFRegTEX0 TEX0, const GSVe
dst->m_TEX0.TBP0, dst->m_TEX0.TBW, psm_str(dst->m_TEX0.PSM));
}

if (dst->m_scale != scale && (!preserve_scale || is_shuffle || (dst->m_downscaled && dst->m_scale >= scale)))
if (dst->m_scale != scale && (!preserve_scale || is_shuffle || (dst->m_downscaled && dst->m_scale >= scale) || TEX0.TBW != dst->m_TEX0.TBW))
{
calcRescale(dst);
GSTexture* tex = type == RenderTarget ? g_gs_device->CreateRenderTarget(new_scaled_size.x, new_scaled_size.y, GSTexture::Format::Color, clear) :
Expand Down

0 comments on commit 2a74cb8

Please sign in to comment.