From b56ff3fce7357470550a5f8a1b5b98f634563949 Mon Sep 17 00:00:00 2001 From: Akash Date: Sat, 31 Dec 2016 19:46:40 +0530 Subject: [PATCH 1/2] GSDX-TC: Pass merged output size for scaling Passes the merged output circuit as the base size for texture cache scaling code. Helps fixing scaling issues where games use both of the output circuits for rendering. Future Note: Alter the behavior of IsEnabled() check always preferring the second output circuit for some weird reason. I plan on changing it to a better auto-output circuit selection mechanism but that could probably be done some time in the future. --- plugins/GSdx/GSState.cpp | 14 +++++++++++--- plugins/GSdx/GSState.h | 2 +- plugins/GSdx/GSTextureCache.cpp | 4 ++-- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/plugins/GSdx/GSState.cpp b/plugins/GSdx/GSState.cpp index 00016372e0..319cf8a8c2 100644 --- a/plugins/GSdx/GSState.cpp +++ b/plugins/GSdx/GSState.cpp @@ -405,7 +405,7 @@ GSVideoMode GSState::GetVideoMode() return videomode; } -GSVector4i GSState::GetDisplayRect(int i) +GSVector4i GSState::GetDisplayRect(int i, bool merged_rect) { if(i < 0) i = IsEnabled(1) ? 1 : 0; @@ -433,8 +433,16 @@ GSVector4i GSState::GetDisplayRect(int i) rectangle.right = rectangle.left + width; rectangle.bottom = rectangle.top + height; - // Useful for debugging games: - //printf("DW: %d , DH: %d , left: %d , right: %d , top: %d , down: %d , MAGH: %d , MAGV: %d\n", m_regs->DISP[i].DISPLAY.DW, m_regs->DISP[i].DISPLAY.DH, r.left, r.right, r.top, r.bottom , m_regs->DISP[i].DISPLAY.MAGH,m_regs->DISP[i].DISPLAY.MAGV); + if ((m_regs->PMODE.EN1 & m_regs->PMODE.EN2) && merged_rect) + { + GSVector4i opposite_output = GetDisplayRect(!i); + GSVector4i r_intersect = opposite_output.rintersect(rectangle); + GSVector4i r_union = opposite_output.runion_ordered(rectangle); + + if(!(r_intersect.width() && r_intersect.height()) || + r_intersect.xyxy().eq(r_union.xyxy())) + return r_union; + } return rectangle; } diff --git a/plugins/GSdx/GSState.h b/plugins/GSdx/GSState.h index 2fad88beb3..d60e684c13 100644 --- a/plugins/GSdx/GSState.h +++ b/plugins/GSdx/GSState.h @@ -242,7 +242,7 @@ public: void ResetHandlers(); - GSVector4i GetDisplayRect(int i = -1); + GSVector4i GetDisplayRect(int i = -1, bool merged_rect = false); GSVector4i GetFrameRect(int i = -1); GSVideoMode GetVideoMode(); diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 58ba33786a..2b9b6e63d3 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -414,8 +414,8 @@ void GSTextureCache::ScaleTexture(GSTexture* texture) if (custom_resolution) { - int width = m_renderer->GetDisplayRect().width(); - int height = m_renderer->GetDisplayRect().height(); + int width = m_renderer->GetDisplayRect(-1, true).width(); + int height = m_renderer->GetDisplayRect(-1, true).height(); int real_height = static_cast(round(m_renderer->GetInternalResolution().y / texture->GetScale().y)); // Fixes offset issues on Persona 3 (512x511) where real value of height is 512 From 6c521c36dd4ac2e5e9ba5b04d10c4de8e326ecc0 Mon Sep 17 00:00:00 2001 From: Akash Date: Sat, 31 Dec 2016 19:53:54 +0530 Subject: [PATCH 2/2] GSdx-TC: Remove some old hacks Previously, we only calculated the width of a single output circuit which lead to missing a single pixel from the other output circuit which in turn causes offset issues in Persona games, I have customized GetDisplayRect() to now also calculate the dimensions of the merged rectangle when both the output circuits are enabled through the PMODE register, so this hack is no longer needed. :) TL;DR - The above commit of mine accurately handles the offset issues by calculating union of the rects, removing this stupid hack. (not insulting any other developers, this stupid hack was mine :) --- plugins/GSdx/GSTextureCache.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 2b9b6e63d3..c7cc57a64a 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -416,11 +416,6 @@ void GSTextureCache::ScaleTexture(GSTexture* texture) { int width = m_renderer->GetDisplayRect(-1, true).width(); int height = m_renderer->GetDisplayRect(-1, true).height(); - int real_height = static_cast(round(m_renderer->GetInternalResolution().y / texture->GetScale().y)); - - // Fixes offset issues on Persona 3 (512x511) where real value of height is 512 - if (real_height % height == 1) - height = real_height; GSVector2i requested_resolution = m_renderer->GetCustomResolution(); scale_factor.x = static_cast(requested_resolution.x) / width;