From 46770aba3a9b76b7cb22b29c417b99574661640e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Sep 2021 22:33:47 -0700 Subject: [PATCH 1/2] Vulkan: Skip flips, not draw, for vsync unthrottle. --- Core/HLE/sceDisplay.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index 98f237b3bc..f4c6910515 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -558,16 +558,7 @@ static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { bool doFrameSkip = g_Config.iFrameSkip != 0; bool fastForwardNeedsSkip = g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_DRAW; - if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { - // Vulkan doesn't support the interval setting, so we force frameskip. - fastForwardNeedsSkip = true; - // If it's not a clean multiple of 60, we may need frameskip to achieve it. - if (fpsLimit == 0 || (fpsLimit >= 0 && fpsLimit != 15 && fpsLimit != 30 && fpsLimit != 60)) { - doFrameSkip = true; - } - } if (!throttle && fastForwardNeedsSkip) { - doFrameSkip = true; skipFrame = true; if (numSkippedFrames >= 7) { skipFrame = false; @@ -751,9 +742,10 @@ void __DisplayFlip(int cyclesLate) { bool duplicateFrames = g_Config.bRenderDuplicateFrames && g_Config.iFrameSkip == 0; bool fastForwardNeedsSkip = g_Config.iFastForwardMode != (int)FastForwardMode::CONTINUOUS; + bool fastForwardSkipFlip = g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_FLIP; if (g_Config.bVSync && GetGPUBackend() == GPUBackend::VULKAN) { - // Vulkan doesn't support the interval setting, so we force frameskip. - fastForwardNeedsSkip = true; + // Vulkan doesn't support the interval setting, so we force skipping the flip. + fastForwardSkipFlip = true; } // postEffectRequiresFlip is not compatible with frameskip fast-forward, see #12325. @@ -788,7 +780,7 @@ void __DisplayFlip(int cyclesLate) { bool forceNoFlip = false; // Alternative to frameskip fast-forward, where we draw everything. // Useful if skipping a frame breaks graphics or for checking drawing speed. - if (g_Config.iFastForwardMode == (int)FastForwardMode::SKIP_FLIP && !FrameTimingThrottled()) { + if (fastForwardSkipFlip && !FrameTimingThrottled()) { static double lastFlip = 0; double now = time_now_d(); if ((now - lastFlip) < 1.0f / System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE)) { From 9024c7111b32493ec692fea497b3f1d8c391bba5 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 14 Sep 2021 22:53:54 -0700 Subject: [PATCH 2/2] Vulkan: Fix faster alt speed with vsync. --- Core/HLE/sceDisplay.cpp | 42 ++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/Core/HLE/sceDisplay.cpp b/Core/HLE/sceDisplay.cpp index f4c6910515..371dea59d4 100644 --- a/Core/HLE/sceDisplay.cpp +++ b/Core/HLE/sceDisplay.cpp @@ -511,14 +511,18 @@ void __DisplaySetWasPaused() { wasPaused = true; } +static int FrameTimingLimit() { + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1) + return g_Config.iFpsLimit1; + if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2) + return g_Config.iFpsLimit2; + if (PSP_CoreParameter().fastForward) + return 0; + return 60; +} + static bool FrameTimingThrottled() { - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 == 0) { - return false; - } - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 == 0) { - return false; - } - return !PSP_CoreParameter().fastForward; + return FrameTimingLimit() != 0; } static void DoFrameDropLogging(float scaledTimestep) { @@ -546,10 +550,7 @@ static int CalculateFrameSkip() { // Let's collect all the throttling and frameskipping logic here. static void DoFrameTiming(bool &throttle, bool &skipFrame, float timestep) { PROFILE_THIS_SCOPE("timing"); - FPSLimit fpsLimiter = PSP_CoreParameter().fpsLimit; - int fpsLimit = 60; - if (fpsLimiter != FPSLimit::NORMAL) - fpsLimit = fpsLimiter == FPSLimit::CUSTOM1 ? g_Config.iFpsLimit1 : g_Config.iFpsLimit2; + int fpsLimit = FrameTimingLimit(); throttle = FrameTimingThrottled(); skipFrame = false; @@ -648,11 +649,10 @@ static void DoFrameIdleTiming() { } float scaledVblank = timePerVblank; - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { + int fpsLimit = FrameTimingLimit(); + if (fpsLimit != 0 && fpsLimit != 60) { // 0 is handled in FrameTimingThrottled(). - scaledVblank *= 60.0f / g_Config.iFpsLimit1; - } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { - scaledVblank *= 60.0f / g_Config.iFpsLimit2; + scaledVblank *= 60.0f / fpsLimit; } // If we have over at least a vblank of spare time, maintain at least 30fps in delay. @@ -778,12 +778,13 @@ void __DisplayFlip(int cyclesLate) { } bool forceNoFlip = false; + float refreshRate = System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE); // Alternative to frameskip fast-forward, where we draw everything. // Useful if skipping a frame breaks graphics or for checking drawing speed. - if (fastForwardSkipFlip && !FrameTimingThrottled()) { + if (fastForwardSkipFlip && (!FrameTimingThrottled() || FrameTimingLimit() > refreshRate)) { static double lastFlip = 0; double now = time_now_d(); - if ((now - lastFlip) < 1.0f / System_GetPropertyFloat(SYSPROP_DISPLAY_REFRESH_RATE)) { + if ((now - lastFlip) < 1.0f / refreshRate) { forceNoFlip = true; } else { lastFlip = now; @@ -876,11 +877,10 @@ void hleLagSync(u64 userdata, int cyclesLate) { } float scale = 1.0f; - if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM1 && g_Config.iFpsLimit1 > 0) { + int fpsLimit = FrameTimingLimit(); + if (fpsLimit != 0 && fpsLimit != 60) { // 0 is handled in FrameTimingThrottled(). - scale = 60.0f / g_Config.iFpsLimit1; - } else if (PSP_CoreParameter().fpsLimit == FPSLimit::CUSTOM2 && g_Config.iFpsLimit2 > 0) { - scale = 60.0f / g_Config.iFpsLimit2; + scale = 60.0f / fpsLimit; } const double goal = lastLagSync + (scale / 1000.0f);