From b10c3570658c617386be47d58f87b9cc790d8250 Mon Sep 17 00:00:00 2001 From: Akash Date: Wed, 8 Nov 2017 12:17:23 +0530 Subject: [PATCH] GSdx-TC: Fix load size calculation in target update Previously, the calculation for the size of data to be loaded was done based on the rendering target buffer size and scaling multiplier, which was totally wrong. This led to different resolutions having different load sizes while the size of the real GS memory is common regardless of the scaling variancies. Hence use the default rendering target buffer size for the load size independent of the scaling values. I've also removed a buffer height saturation code which seemed unreliable. Note: The accurate version of the code can be enabled using the macro provided in config.h (which is more intensive on resources), the current code goes along with the approach of maintaining a decent performance level along with a formidable accuracy. --- plugins/GSdx/GS.h | 6 ++++++ plugins/GSdx/GSRendererHW.cpp | 8 ++++---- plugins/GSdx/GSRendererHW.h | 1 - plugins/GSdx/GSTextureCache.cpp | 17 ++++++----------- plugins/GSdx/config.h | 1 + 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/plugins/GSdx/GS.h b/plugins/GSdx/GS.h index 5b785a72d1..3474f3c584 100644 --- a/plugins/GSdx/GS.h +++ b/plugins/GSdx/GS.h @@ -1449,3 +1449,9 @@ enum class CRCHackLevel : int8 Full, Aggressive }; + +#ifdef ENABLE_ACCURATE_BUFFER_EMULATION +const GSVector2i default_rt_size(2048, 2048); +#else +const GSVector2i default_rt_size(1280, 1024); +#endif diff --git a/plugins/GSdx/GSRendererHW.cpp b/plugins/GSdx/GSRendererHW.cpp index c6cd844482..d0ff819884 100644 --- a/plugins/GSdx/GSRendererHW.cpp +++ b/plugins/GSdx/GSRendererHW.cpp @@ -23,8 +23,8 @@ #include "GSRendererHW.h" GSRendererHW::GSRendererHW(GSTextureCache* tc) - : m_width(native_buffer.x) - , m_height(native_buffer.y) + : m_width(default_rt_size.x) + , m_height(default_rt_size.y) , m_custom_width(1024) , m_custom_height(1024) , m_reset(false) @@ -158,8 +158,8 @@ void GSRendererHW::CustomResolutionScaling() return; m_tc->RemovePartial(); - m_width = std::max(m_width, native_buffer.x); - m_height = std::max(framebuffer_height[m_large_framebuffer], native_buffer.y); + m_width = std::max(m_width, default_rt_size.x); + m_height = std::max(framebuffer_height[m_large_framebuffer], default_rt_size.y); std::string overhead = std::to_string(framebuffer_height[1] - framebuffer_height[0]); std::string message = "(Custom resolution) Framebuffer size set to " + std::to_string(crtc_width) + "x" + std::to_string(crtc_height); diff --git a/plugins/GSdx/GSRendererHW.h b/plugins/GSdx/GSRendererHW.h index 8343bdf341..a4aa5213a7 100644 --- a/plugins/GSdx/GSRendererHW.h +++ b/plugins/GSdx/GSRendererHW.h @@ -30,7 +30,6 @@ class GSRendererHW : public GSRenderer { private: - GSVector2i native_buffer = GSVector2i{1280, 1024}; int m_width; int m_height; int m_custom_width; diff --git a/plugins/GSdx/GSTextureCache.cpp b/plugins/GSdx/GSTextureCache.cpp index 857591d886..c69bdaff99 100644 --- a/plugins/GSdx/GSTextureCache.cpp +++ b/plugins/GSdx/GSTextureCache.cpp @@ -1847,18 +1847,13 @@ void GSTextureCache::Target::Update() // Alternate // 1/ uses multiple vertex rectangle - GSVector2i t_size = m_texture->GetSize(); - GSVector2 t_scale = m_texture->GetScale(); + GSVector2i t_size = default_rt_size; - //Avoids division by zero when calculating texture size. - t_scale = GSVector2(std::max(1.0f, t_scale.x), std::max(1.0f, t_scale.y)); - t_size.x = lround(static_cast(t_size.x) / t_scale.x); - t_size.y = lround(static_cast(t_size.y) / t_scale.y); - - // Don't load above the GS memory - int max_y_blocks = (MAX_BLOCKS - m_TEX0.TBP0) / std::max(1u, m_TEX0.TBW); - int max_y = (max_y_blocks >> 5) * GSLocalMemory::m_psm[m_TEX0.PSM].pgs.y; - t_size.y = std::min(t_size.y, max_y); + // Ensure buffer width is at least of the minimum required value. + // Probably not necessary but doesn't hurt to be on the safe side. + // I've seen some games use buffer sizes over 1024, which might bypass our default limit + int buffer_width = m_TEX0.TBW << 6; + t_size.x = std::max(buffer_width, t_size.x); GSVector4i r = m_dirty.GetDirtyRectAndClear(m_TEX0, t_size); diff --git a/plugins/GSdx/config.h b/plugins/GSdx/config.h index d22a54c688..877cd78c8b 100644 --- a/plugins/GSdx/config.h +++ b/plugins/GSdx/config.h @@ -23,6 +23,7 @@ //#define ENABLE_VTUNE //#define ENABLE_PCRTC_DEBUG +//#define ENABLE_ACCURATE_BUFFER_EMULATION #define ENABLE_JIT_RASTERIZER #define EXTERNAL_SHADER_LOADING 1