From 0b5c070ad14798454576014f371e32540d4e0de2 Mon Sep 17 00:00:00 2001 From: Stenzek Date: Sun, 15 Oct 2023 15:00:52 +1000 Subject: [PATCH] GS/HW: Restore off-by-one clamp when upscaling Xenosaga and VP2 break otherwise. Xenosaga draws a line around the RT, which is offset by 1 row/column, which the off-by-one clamp was previously masking. VP2 is just a can of worms I don't have the energy to deal with at the moment. --- pcsx2/GS/Renderers/HW/GSRendererHW.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp index ba7386100f..4371022a30 100644 --- a/pcsx2/GS/Renderers/HW/GSRendererHW.cpp +++ b/pcsx2/GS/Renderers/HW/GSRendererHW.cpp @@ -4377,10 +4377,13 @@ __ri void GSRendererHW::EmulateTextureSampler(const GSTextureCache::Target* rt, if (complex_wms_wmt) { // Add 0.5 to the coordinates because the region clamp is inclusive, size is exclusive. We use 0.5 because we want to clamp - // to the last texel in the image, not halfway between it and wrapping around. + // to the last texel in the image, not halfway between it and wrapping around. We *should* be doing this when upscaling, + // but having it off-by-one masks some draw issues in VP2 and Xenosaga. TODO: Fix the underlying draw issues. const GSVector4i clamp(m_cached_ctx.CLAMP.MINU, m_cached_ctx.CLAMP.MINV, m_cached_ctx.CLAMP.MAXU, m_cached_ctx.CLAMP.MAXV); const GSVector4 region_repeat = GSVector4::cast(clamp); - const GSVector4 region_clamp = (GSVector4(clamp) + GSVector4::cxpr(0.0f, 0.0f, 0.5f, 0.5f)) / WH.xyxy(); + const GSVector4 region_clamp_offset = + (tex->GetScale() != 1.0f) ? GSVector4::cxpr(0.0f, 0.0f, 0.0f, 0.0f) : GSVector4::cxpr(0.0f, 0.0f, 0.5f, 0.5f); + const GSVector4 region_clamp = (GSVector4(clamp) + region_clamp_offset) / WH.xyxy(); if (wms >= CLAMP_REGION_CLAMP) { m_conf.cb_ps.MinMax.x = (wms == CLAMP_REGION_CLAMP && !m_conf.ps.depth_fmt) ? region_clamp.x : region_repeat.x;