GS-PCRTC: Remove frame offset from anti-blur hacks in software.

Turns out this is now more detrimental than an improvement
This commit is contained in:
refractionpcsx2 2022-07-22 15:17:11 +01:00
parent de8b23db4e
commit fc611dee57
2 changed files with 39 additions and 25 deletions

View File

@ -147,7 +147,8 @@ bool GSRenderer::Merge(int field)
s_n++;
if (samesrc && fr[0].bottom == fr[1].bottom && !feedback_merge && fr[0].right == fr[1].right)
// Only need to check the right/bottom on software renderer, hardware always gets the full texture then cuts a bit out later.
if (samesrc && !feedback_merge && (GSConfig.UseHardwareRenderer() || (fr[0].right == fr[1].right && fr[0].bottom == fr[1].bottom)))
{
tex[0] = GetOutput(0, y_offset[0]);
tex[1] = tex[0]; // saves one texture fetch
@ -200,11 +201,14 @@ bool GSRenderer::Merge(int field)
GSVector2i display_diff(display_offsets[i].x - display_baseline.x, display_offsets[i].y - display_baseline.y);
GSVector2i frame_diff(fr[i].left - frame_baseline.x, fr[i].top - frame_baseline.y);
if (!GSConfig.UseHardwareRenderer())
{
// Clear any frame offsets, we don't need them now.
fr[i].right -= fr[i].left;
fr[i].left = 0;
fr[i].bottom -= fr[i].top;
fr[i].top = 0;
}
// If using scanmsk we have to keep the single line offset, regardless of upscale
// so we handle this separately after the rect calculations.
@ -239,6 +243,9 @@ bool GSRenderer::Merge(int field)
if (display_diff.y < 4)
off.y -= display_diff.y;
// Only functional in HW mode, software clips/positions the framebuffer on read.
if (GSConfig.UseHardwareRenderer())
{
// Offset by DISPFB setting
if (abs(frame_diff.x) < 4)
off.x += frame_diff.x;
@ -247,6 +254,7 @@ bool GSRenderer::Merge(int field)
}
}
}
}
else
{
if (!slbg || !feedback_merge)
@ -289,7 +297,8 @@ bool GSRenderer::Merge(int field)
off.y += display_baseline.y;
// Anti-Blur stuff
if (GSConfig.PCRTCAntiBlur)
// Only functional in HW mode, software clips/positions the framebuffer on read.
if (GSConfig.PCRTCAntiBlur && GSConfig.UseHardwareRenderer())
{
// Offset by DISPFB setting
if (abs(frame_diff.x) < 4)

View File

@ -35,7 +35,6 @@ GSRendererSW::GSRendererSW(int threads)
m_tc = std::make_unique<GSTextureCacheSW>();
m_rl = GSRasterizerList::Create<GSDrawScanline>(threads);
// Max framebuffer size can be 1024x2048 (it will loop at 2048).
m_output = (u8*)_aligned_malloc(1024 * 1024 * sizeof(u32), 32);
std::fill(std::begin(m_fzb_pages), std::end(m_fzb_pages), 0);
@ -146,46 +145,52 @@ GSTexture* GSRendererSW::GetOutput(int i, int& y_offset)
constexpr int pitch = 1024 * 4;
const int off_x = DISPFB.DBX & 0x7ff;
const int off_y = DISPFB.DBY & 0x7ff;
bool part2_h = false;
bool part2_w = false;
const GSVector4i out_r(0, 0, w, h);
GSVector4i r(off_x, off_y, w + off_x, h + off_y);
GSVector4i rh(off_x, off_y, w + off_x, (h + off_y) & 0x7FF);
GSVector4i rw(off_x, off_y, (w + off_x) & 0x7FF, h + off_y);
GSVector4i out_r(0, 0, w, h);
bool h_wrap = false;
bool w_wrap = false;
// Need to read it in 2 parts, since you can't do a split rect.
if (r.bottom >= 2048)
{
r.bottom = 2048;
rw.bottom = 2048;
part2_h = true;
rh.top = 0;
h_wrap = true;
}
if (r.right >= 2048)
{
r.right = 2048;
rh.right = 2048;
part2_w = true;
rw.left = 0;
w_wrap = true;
}
const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[DISPFB.PSM];
// Top left rect
(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), r.ralign<Align_Outside>(psm.bs), m_output, pitch, m_env.TEXA);
int top = (part2_h) ? ((r.bottom - r.top) * pitch) : 0;
int left = (part2_w) ? (r.right - r.left) * (GSLocalMemory::m_psm[DISPFB.PSM].bpp / 8) : 0;
int top = (h_wrap) ? ((r.bottom - r.top) * pitch) : 0;
int left = (w_wrap) ? (r.right - r.left) * (GSLocalMemory::m_psm[DISPFB.PSM].bpp / 8) : 0;
if (part2_w)
// The following only happen if the DBX/DBY wrap around at 2048.
// Top right rect
if (w_wrap)
(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), rw.ralign<Align_Outside>(psm.bs), &m_output[left], pitch, m_env.TEXA);
if (part2_h)
// Bottom left rect
if (h_wrap)
(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), rh.ralign<Align_Outside>(psm.bs), &m_output[top], pitch, m_env.TEXA);
if (part2_h && part2_w)
// Bottom right rect
if (h_wrap && w_wrap)
{
// needs also rw with the start/end height of rh, fills in the bottom right rect which will be missing if both overflow.
// Needs also rw with the start/end height of rh, fills in the bottom right rect which will be missing if both overflow.
const GSVector4i rwh(rw.left, rh.top, rw.right, rh.bottom);
(m_mem.*psm.rtx)(m_mem.GetOffset(DISPFB.Block(), DISPFB.FBW, DISPFB.PSM), rwh.ralign<Align_Outside>(psm.bs), &m_output[top + left], pitch, m_env.TEXA);
}