From 1b3b1acefacd0652fc52aa2c6dde619b855deb36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 30 Aug 2022 20:10:44 +0200 Subject: [PATCH] Tweak ForceMax60Fps to work for Killzone --- Core/HLE/sceDisplay.cpp | 5 ++++- GPU/Common/FramebufferManagerCommon.cpp | 3 ++- GPU/Common/TextureCacheCommon.cpp | 7 ++++++- assets/compat.ini | 8 ++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 7db5998ff7..d0577d46f2 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -823,7 +823,10 @@ u32 sceDisplaySetFramebuf(u32 topaddr, int linesize, int pixelformat, int sync) s64 delayCycles = 0; // Don't count transitions between display off and display on. - if (topaddr != 0 && topaddr != framebuf.topaddr && framebuf.topaddr != 0 && PSP_CoreParameter().compat.flags().ForceMax60FPS) { + if (topaddr != 0 && + (topaddr != framebuf.topaddr || PSP_CoreParameter().compat.flags().SplitFramebufferMargin) && + framebuf.topaddr != 0 && + PSP_CoreParameter().compat.flags().ForceMax60FPS) { // sceDisplaySetFramebuf() isn't supposed to delay threads at all. This is a hack. // So let's only delay when it's more than 1ms. const s64 FLIP_DELAY_CYCLES_MIN = usToCycles(1000); diff --git a/GPU/Common/FramebufferManagerCommon.cpp b/GPU/Common/FramebufferManagerCommon.cpp index 6aff9382d4..d376f2c91e 100644 --- a/GPU/Common/FramebufferManagerCommon.cpp +++ b/GPU/Common/FramebufferManagerCommon.cpp @@ -679,7 +679,8 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra // This will result in reinterpret later, if both formats are 16-bit. sources.push_back(CopySource{ src, RASTER_COLOR, 0, 0 }); } else { - // Likely irrelevant or old, if the game is changing color depth for example. + // This shouldn't happen anymore. I think when it happened last, we still had + // lax stride checking when video was incoming, and a resize happened causing a duplicate. } } else if (src->fb_stride == dst->fb_stride && src->fb_format == dst->fb_format) { u32 bytesPerPixel = BufferFormatBytesPerPixel(src->fb_format); diff --git a/GPU/Common/TextureCacheCommon.cpp b/GPU/Common/TextureCacheCommon.cpp index 3fe20676da..8f4e08a12f 100644 --- a/GPU/Common/TextureCacheCommon.cpp +++ b/GPU/Common/TextureCacheCommon.cpp @@ -664,6 +664,8 @@ int TextureCacheCommon::GetBestCandidateIndex(const std::vector int bestRelevancy = -1; int bestIndex = -1; + bool kzCompat = PSP_CoreParameter().compat.flags().SplitFramebufferMargin; + // We simply use the sequence counter as relevancy nowadays. for (int i = 0; i < (int)candidates.size(); i++) { const AttachCandidate &candidate = candidates[i]; @@ -677,7 +679,10 @@ int TextureCacheCommon::GetBestCandidateIndex(const std::vector relevancy -= 2; } - if (candidate.fb == framebufferManager_->GetCurrentRenderVFB()) { + // Avoid binding as texture the framebuffer we're rendering to. + // In Killzone, we split the framebuffer but the matching algorithm can still pick the wrong one, + // which this avoids completely. + if (kzCompat && candidate.fb == framebufferManager_->GetCurrentRenderVFB()) { continue; } diff --git a/assets/compat.ini b/assets/compat.ini index f928684a28..4b2fb0545d 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -1004,6 +1004,14 @@ ULUS10317 = true ULUS10598 = true ULES01578 = true +# Killzone: Liberation (see issue #6207) +UCES00279 = true +UCKS45041 = true +UCUS98646 = true +UCET00278 = true +UCUS98670 = true +UCUS98646 = true + [JitInvalidationHack] # This is an absolutely awful hack that somehow prevents issues when clearing the JIT, # if the game has copied code with EmuHack opcodes or something. Hopefully will be able