From 01f65e98e60d80f4a2c879f28f61133743aaea42 Mon Sep 17 00:00:00 2001 From: refractionpcsx2 Date: Wed, 15 Feb 2023 20:26:13 +0000 Subject: [PATCH] GS-PCRTC: Fix up some PCRTC anti-blur behaviour + code cleanup --- pcsx2/GS/GSState.h | 28 ++++++++++++++++-------- pcsx2/GS/Renderers/Common/GSRenderer.cpp | 4 ++-- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pcsx2/GS/GSState.h b/pcsx2/GS/GSState.h index 92062114d9..0ac7040137 100644 --- a/pcsx2/GS/GSState.h +++ b/pcsx2/GS/GSState.h @@ -355,7 +355,7 @@ public: bool IsAnalogue() { - GSVideoMode video = static_cast(videomode + 1); + const GSVideoMode video = static_cast(videomode + 1); return video == GSVideoMode::NTSC || video == GSVideoMode::PAL || video == GSVideoMode::HDTV_1080I; } @@ -382,7 +382,7 @@ public: returnValue.x = 0; // When interlaced, the vertical base offset is doubled - int verticalOffset = VideoModeOffsets[videomode].w * (1 << interlaced); + const int verticalOffset = VideoModeOffsets[videomode].w * (1 << interlaced); if (abs(PCRTCDisplays[0].displayOffset.y - verticalOffset) < abs(PCRTCDisplays[1].displayOffset.y - verticalOffset)) @@ -422,7 +422,7 @@ public: bool FrameWrap() { - GSVector4i combined_rect = GSVector4i(PCRTCDisplays[0].framebufferRect.runion(PCRTCDisplays[1].framebufferRect)); + const GSVector4i combined_rect = GSVector4i(PCRTCDisplays[0].framebufferRect.runion(PCRTCDisplays[1].framebufferRect)); return combined_rect.w >= 2048 || combined_rect.z >= 2048; } @@ -443,7 +443,7 @@ public: { if (PCRTCDisplays[0].enabled && PCRTCDisplays[1].enabled) { - GSVector4i combined_size = PCRTCDisplays[0].displayRect.runion(PCRTCDisplays[1].displayRect); + const GSVector4i combined_size = PCRTCDisplays[0].displayRect.runion(PCRTCDisplays[1].displayRect); resolution = { combined_size.width(), combined_size.height() }; } else if (PCRTCDisplays[0].enabled) @@ -504,20 +504,20 @@ public: if (combined_rect.z >= 2048) { - int high_x = (PCRTCDisplays[0].framebufferRect.x > PCRTCDisplays[1].framebufferRect.x) ? PCRTCDisplays[0].framebufferRect.x : PCRTCDisplays[1].framebufferRect.x; + const int high_x = (PCRTCDisplays[0].framebufferRect.x > PCRTCDisplays[1].framebufferRect.x) ? PCRTCDisplays[0].framebufferRect.x : PCRTCDisplays[1].framebufferRect.x; combined_rect.z -= GSConfig.UseHardwareRenderer() ? 2048 : high_x; combined_rect.x = 0; } if (combined_rect.w >= 2048) { - int high_y = (PCRTCDisplays[0].framebufferRect.y > PCRTCDisplays[1].framebufferRect.y) ? PCRTCDisplays[0].framebufferRect.y : PCRTCDisplays[1].framebufferRect.y; + const int high_y = (PCRTCDisplays[0].framebufferRect.y > PCRTCDisplays[1].framebufferRect.y) ? PCRTCDisplays[0].framebufferRect.y : PCRTCDisplays[1].framebufferRect.y; combined_rect.w -= GSConfig.UseHardwareRenderer() ? 2048 : high_y; combined_rect.y = 0; } // Cap the framebuffer read to the maximum display height, otherwise the hardware renderer gets messy. - int min_mag = std::max(1, std::min(PCRTCDisplays[0].magnification.y, PCRTCDisplays[1].magnification.y)); + const int min_mag = std::max(1, std::min(PCRTCDisplays[0].magnification.y, PCRTCDisplays[1].magnification.y)); combined_rect.w = std::min(combined_rect.w, combined_rect.y + (max_height / min_mag)); return GSVector2i(combined_rect.z, combined_rect.w); } @@ -613,16 +613,24 @@ public: // Only considered if "Anti-blur" is enabled. void CalculateFramebufferOffset() { - if (GSConfig.PCRTCAntiBlur && PCRTCDisplays[0].enabled && PCRTCSameSrc) + if (GSConfig.PCRTCAntiBlur && PCRTCSameSrc) { if (abs(PCRTCDisplays[1].framebufferOffsets.y - PCRTCDisplays[0].framebufferOffsets.y) == 1 - && PCRTCDisplays[0].displayOffset.y == PCRTCDisplays[1].displayOffset.y) + && PCRTCDisplays[0].displayRect.y == PCRTCDisplays[1].displayRect.y) { if (PCRTCDisplays[1].framebufferOffsets.y < PCRTCDisplays[0].framebufferOffsets.y) PCRTCDisplays[0].framebufferOffsets.y = PCRTCDisplays[1].framebufferOffsets.y; else PCRTCDisplays[1].framebufferOffsets.y = PCRTCDisplays[0].framebufferOffsets.y; } + if (abs(PCRTCDisplays[1].framebufferOffsets.x - PCRTCDisplays[0].framebufferOffsets.x) == 1 + && PCRTCDisplays[0].displayRect.x == PCRTCDisplays[1].displayRect.x) + { + if (PCRTCDisplays[1].framebufferOffsets.x < PCRTCDisplays[0].framebufferOffsets.x) + PCRTCDisplays[0].framebufferOffsets.x = PCRTCDisplays[1].framebufferOffsets.x; + else + PCRTCDisplays[1].framebufferOffsets.x = PCRTCDisplays[0].framebufferOffsets.x; + } } PCRTCDisplays[0].framebufferRect.x += PCRTCDisplays[0].framebufferOffsets.x; PCRTCDisplays[0].framebufferRect.z += PCRTCDisplays[0].framebufferOffsets.x; @@ -658,6 +666,7 @@ public: { const GSLocalMemory::psm_t& psm = GSLocalMemory::m_psm[PCRTCDisplays[display].PSM]; + // Software mode - See note below. GSVector4i r = PCRTCDisplays[display].framebufferRect; r = r.ralign(psm.bs); @@ -669,6 +678,7 @@ public: } else { + // Software Mode Note: // This code is to read the framebuffer nicely block aligned in software, then leave the remaining offset in to the block. // In hardware mode this doesn't happen, it reads the whole framebuffer, so we need to keep the offset. if (!GSConfig.UseHardwareRenderer()) diff --git a/pcsx2/GS/Renderers/Common/GSRenderer.cpp b/pcsx2/GS/Renderers/Common/GSRenderer.cpp index 04da9596c8..3d3647e899 100644 --- a/pcsx2/GS/Renderers/Common/GSRenderer.cpp +++ b/pcsx2/GS/Renderers/Common/GSRenderer.cpp @@ -80,10 +80,11 @@ bool GSRenderer::Merge(int field) GSVector2i fs(0, 0); GSTexture* tex[3] = { NULL, NULL, NULL }; int y_offset[3] = { 0, 0, 0 }; - bool feedback_merge = m_regs->EXTWRITE.WRITE == 1; + const bool feedback_merge = m_regs->EXTWRITE.WRITE == 1; PCRTCDisplays.SetVideoMode(GetVideoMode()); PCRTCDisplays.EnableDisplays(m_regs->PMODE, m_regs->SMODE2, isReallyInterlaced()); + PCRTCDisplays.CheckSameSource(); if (!PCRTCDisplays.PCRTCDisplays[0].enabled && !PCRTCDisplays.PCRTCDisplays[1].enabled) return false; @@ -96,7 +97,6 @@ bool GSRenderer::Merge(int field) PCRTCDisplays.SetRects(1, m_regs->DISP[1].DISPLAY, m_regs->DISP[1].DISPFB); PCRTCDisplays.CalculateDisplayOffset(m_scanmask_used); PCRTCDisplays.CalculateFramebufferOffset(); - PCRTCDisplays.CheckSameSource(); // Only need to check the right/bottom on software renderer, hardware always gets the full texture then cuts a bit out later. if (PCRTCDisplays.FrameRectMatch() && !PCRTCDisplays.FrameWrap() && !feedback_merge)