From 0ae91cbf649987a3ea9b8a925779cdd2ea3a5778 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Sat, 13 May 2023 02:01:48 +0100 Subject: [PATCH] GS-HW: Fix annoying NASCAR offsets in PCRTC --- pcsx2/GS/GSState.h | 20 ++++++-------------- pcsx2/GS/Renderers/SW/GSRendererSW.cpp | 11 +++++------ 2 files changed, 11 insertions(+), 20 deletions(-) diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index c610505bbc..49ea29dda7 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -542,16 +542,10 @@ public: GSVector4i out_rect = PCRTCDisplays[display].framebufferRect; if (out_rect.z >= 2048) - { - out_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.x; - out_rect.x = 0; - } + out_rect.z -= out_rect.x; if (out_rect.w >= 2048) - { - out_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : out_rect.y; - out_rect.y = 0; - } + out_rect.w -= out_rect.y; // Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy. const int min_mag = std::max(1, PCRTCDisplays[display].magnification.y); @@ -565,12 +559,6 @@ public: offset = (max_height / min_mag) - offset; out_rect.w = std::min(out_rect.w, offset); - // Hardware mode needs a wider framebuffer as it can't offset the read. - if (GSConfig.UseHardwareRenderer()) - { - out_rect.z += PCRTCDisplays[display].framebufferOffsets.x; - out_rect.w += PCRTCDisplays[display].framebufferOffsets.y; - } return GSVector2i(out_rect.z, out_rect.w); } } @@ -685,11 +673,15 @@ public: { if (PCRTCDisplays[display].framebufferRect.z >= 2048) { + PCRTCDisplays[display].displayRect.x += 2048 - PCRTCDisplays[display].framebufferRect.x; + PCRTCDisplays[display].displayRect.z += 2048 - PCRTCDisplays[display].framebufferRect.x; PCRTCDisplays[display].framebufferRect.x = 0; PCRTCDisplays[display].framebufferRect.z -= 2048; } if (PCRTCDisplays[display].framebufferRect.w >= 2048) { + PCRTCDisplays[display].displayRect.y += 2048 - PCRTCDisplays[display].framebufferRect.y; + PCRTCDisplays[display].displayRect.w += 2048 - PCRTCDisplays[display].framebufferRect.y; PCRTCDisplays[display].framebufferRect.y = 0; PCRTCDisplays[display].framebufferRect.w -= 2048; } diff --git a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp index 9f4739b57a..85af860c4a 100644 --- a/pcsx2/GS/Renderers/SW/GSRendererSW.cpp +++ b/pcsx2/GS/Renderers/SW/GSRendererSW.cpp @@ -124,11 +124,13 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset) constexpr int pitch = 1024 * 4; // Should really be framebufferOffsets rather than framebufferRect but this might be compensated with anti-blur in some games. const int off_x = (framebufferRect.x & 0x7ff) & ~(psm.bs.x-1); + const int off_x_end = ((framebufferRect.x & 0x7ff) + (psm.bs.x - 1)) & ~(psm.bs.x - 1); const int off_y = (framebufferRect.y & 0x7ff) & ~(psm.bs.y-1); + const int off_y_end = ((framebufferRect.y & 0x7ff) + (psm.bs.y - 1)) & ~(psm.bs.y - 1); 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 r(off_x, off_y, w + off_x_end, h + off_y_end); + GSVector4i rh(off_x, off_y, w + off_x_end, (h + off_y_end) & 0x7FF); + GSVector4i rw(off_x, off_y, (w + off_x_end) & 0x7FF, h + off_y_end); bool h_wrap = false; bool w_wrap = false; @@ -159,9 +161,6 @@ GSTexture* GSRendererSW::GetOutput(int i, float& scale, int& y_offset) // Top left rect psm.rtx(m_mem, m_mem.GetOffset(curFramebuffer.Block(), curFramebuffer.FBW, curFramebuffer.PSM), r.ralign(psm.bs), m_output, pitch, texa); - // Top left rect - psm.rtx(m_mem, m_mem.GetOffset(curFramebuffer.Block(), curFramebuffer.FBW, curFramebuffer.PSM), r.ralign(psm.bs), m_output, pitch, texa); - int top = (h_wrap) ? ((r.bottom - r.top) * pitch) : 0; int left = (w_wrap) ? (r.right - r.left) * (GSLocalMemory::m_psm[curFramebuffer.PSM].bpp / 8) : 0;