From 9c55e1e0de1fb523528bf7e75a85762f5a1000e7 Mon Sep 17 00:00:00 2001 From: Henrik Rydgard Date: Sat, 28 Jan 2017 10:04:50 +0100 Subject: [PATCH] Only enable RAM Clears for the SOCOM games that require it. Should remove the performance impact of #8994 which is bigger than expected, it seems (cache pollution?) --- Core/Compatibility.cpp | 11 ++++++----- Core/Compatibility.h | 3 ++- GPU/Common/DrawEngineCommon.cpp | 2 ++ GPU/Directx9/DrawEngineDX9.cpp | 2 +- GPU/Directx9/GPU_DX9.cpp | 4 ++++ GPU/GLES/DrawEngineGLES.cpp | 2 +- GPU/GLES/GPU_GLES.cpp | 4 ++++ GPU/GPUState.h | 1 + GPU/Vulkan/DrawEngineVulkan.cpp | 2 +- GPU/Vulkan/GPU_Vulkan.cpp | 5 +++++ assets/compat.ini | 12 ++++++++++++ 11 files changed, 39 insertions(+), 9 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index 07ec5b627b..7d46e4cf85 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -45,11 +45,12 @@ void Compatibility::Clear() { } void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { - CheckSetting(iniFile, gameID, "VertexDepthRounding", flags_.VertexDepthRounding); - CheckSetting(iniFile, gameID, "PixelDepthRounding", flags_.PixelDepthRounding); - CheckSetting(iniFile, gameID, "DepthRangeHack", flags_.DepthRangeHack); + CheckSetting(iniFile, gameID, "VertexDepthRounding", &flags_.VertexDepthRounding); + CheckSetting(iniFile, gameID, "PixelDepthRounding", &flags_.PixelDepthRounding); + CheckSetting(iniFile, gameID, "DepthRangeHack", &flags_.DepthRangeHack); + CheckSetting(iniFile, gameID, "ClearToRAM", &flags_.ClearToRAM); } -void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool &flag) { - iniFile.Get(option, gameID.c_str(), &flag, flag); +void Compatibility::CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag) { + iniFile.Get(option, gameID.c_str(), flag, *flag); } diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 90413934cf..53d70e5bea 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -48,6 +48,7 @@ struct CompatFlags { bool VertexDepthRounding; bool PixelDepthRounding; bool DepthRangeHack; + bool ClearToRAM; }; class IniFile; @@ -66,7 +67,7 @@ public: private: void Clear(); void CheckSettings(IniFile &iniFile, const std::string &gameID); - void CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool &flag); + void CheckSetting(IniFile &iniFile, const std::string &gameID, const char *option, bool *flag); CompatFlags flags_; }; \ No newline at end of file diff --git a/GPU/Common/DrawEngineCommon.cpp b/GPU/Common/DrawEngineCommon.cpp index c25eca6839..1775023be8 100644 --- a/GPU/Common/DrawEngineCommon.cpp +++ b/GPU/Common/DrawEngineCommon.cpp @@ -140,6 +140,8 @@ void DrawEngineCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2, u32 cl } // This will most often be true - rarely is the width not aligned. + // TODO: We should really use non-temporal stores here to avoid the cache, + // as it's unlikely that these bytes will be read. if ((width & 3) == 0 && (x1 & 3) == 0) { u64 val64 = clearColor | ((u64)clearColor << 32); int xstride = 2; diff --git a/GPU/Directx9/DrawEngineDX9.cpp b/GPU/Directx9/DrawEngineDX9.cpp index eeb2f87831..65abfc6d25 100644 --- a/GPU/Directx9/DrawEngineDX9.cpp +++ b/GPU/Directx9/DrawEngineDX9.cpp @@ -864,7 +864,7 @@ rotateVBO: int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } diff --git a/GPU/Directx9/GPU_DX9.cpp b/GPU/Directx9/GPU_DX9.cpp index b1b36b7dfe..27f299e395 100644 --- a/GPU/Directx9/GPU_DX9.cpp +++ b/GPU/Directx9/GPU_DX9.cpp @@ -503,6 +503,10 @@ void GPU_DX9::CheckGPUFeatures() { features |= GPU_ROUND_DEPTH_TO_16BIT; } + if (PSP_CoreParameter().compat.flags().ClearToRAM) { + features |= GPU_USE_CLEAR_RAM_HACK; + } + gstate_c.featureFlags = features; } diff --git a/GPU/GLES/DrawEngineGLES.cpp b/GPU/GLES/DrawEngineGLES.cpp index e5f9f4562e..367017562b 100644 --- a/GPU/GLES/DrawEngineGLES.cpp +++ b/GPU/GLES/DrawEngineGLES.cpp @@ -977,7 +977,7 @@ rotateVBO: int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && colorMask && (alphaMask || gstate.FrameBufFormat() == GE_FORMAT_565)) { ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, clearColor); } } diff --git a/GPU/GLES/GPU_GLES.cpp b/GPU/GLES/GPU_GLES.cpp index 6b6b04bb49..a3eaab44b0 100644 --- a/GPU/GLES/GPU_GLES.cpp +++ b/GPU/GLES/GPU_GLES.cpp @@ -607,6 +607,10 @@ void GPU_GLES::CheckGPUFeatures() { features |= GPU_USE_DEPTH_RANGE_HACK; } + if (PSP_CoreParameter().compat.flags().ClearToRAM) { + features |= GPU_USE_CLEAR_RAM_HACK; + } + #ifdef MOBILE_DEVICE // Arguably, we should turn off GPU_IS_MOBILE on like modern Tegras, etc. features |= GPU_IS_MOBILE; diff --git a/GPU/GPUState.h b/GPU/GPUState.h index 56536de9f7..8114faadc2 100644 --- a/GPU/GPUState.h +++ b/GPU/GPUState.h @@ -455,6 +455,7 @@ enum { GPU_USE_DEPTH_RANGE_HACK = FLAG_BIT(6), GPU_SUPPORTS_WIDE_LINES = FLAG_BIT(7), GPU_SUPPORTS_ANISOTROPY = FLAG_BIT(8), + GPU_USE_CLEAR_RAM_HACK = FLAG_BIT(9), GPU_SUPPORTS_LARGE_VIEWPORTS = FLAG_BIT(16), GPU_SUPPORTS_ACCURATE_DEPTH = FLAG_BIT(17), GPU_SUPPORTS_VAO = FLAG_BIT(18), diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index d676649502..b888b9cda0 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -852,7 +852,7 @@ void DrawEngineVulkan::DoFlush(VkCommandBuffer cmd) { int scissorY2 = gstate.getScissorY2() + 1; framebufferManager_->SetSafeSize(scissorX2, scissorY2); - if (g_Config.bBlockTransferGPU && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { + if (g_Config.bBlockTransferGPU && (gstate_c.featureFlags & GPU_USE_CLEAR_RAM_HACK) && gstate.isClearModeColorMask() && (gstate.isClearModeAlphaMask() || gstate.FrameBufFormat() == GE_FORMAT_565)) { ApplyClearToMemory(scissorX1, scissorY1, scissorX2, scissorY2, result.color); } } diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 3e065f0d1f..9973f917bb 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -474,6 +474,11 @@ void GPU_Vulkan::CheckGPUFeatures() { if (vulkan_->GetFeaturesEnabled().samplerAnisotropy) { gstate_c.featureFlags |= GPU_SUPPORTS_ANISOTROPY; } + + if (PSP_CoreParameter().compat.flags().ClearToRAM) { + gstate_c.featureFlags |= GPU_USE_CLEAR_RAM_HACK; + } + // Mandatory features on Vulkan, which may be checked in "centralized" code gstate_c.featureFlags |= GPU_SUPPORTS_TEXTURE_LOD_CONTROL; gstate_c.featureFlags |= GPU_SUPPORTS_FBO; diff --git a/assets/compat.ini b/assets/compat.ini index 58d3a2f7f9..31d86c8cc2 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -101,3 +101,15 @@ ULJM91018 = true # Infinity demo disc? NPJH90157 = true # Infinity demo ULJM05732 = true NPJH50332 = true + +[ClearToRAM] +# SOCOM Navy Seals games require this. See issue #8973. +# Navy Seals +UCUS98615 = true +ULES00038 = true +UCKS45021 = true +# Fireteam Bravo 3 +UCJS10102 = true +NPJG00035 = true +UCUS98716 = true +UCES01242 = true \ No newline at end of file