aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaranBr <maranbr@outlook.com>2026-03-02 02:53:01 +0100
committercrueter <crueter@eden-emu.dev>2026-03-02 02:53:01 +0100
commitea209e6dabdcd99f51dd2ae8b11adeb715b9668f (patch)
treeb405342e03348c907e5c777fc0ab8bd23ef15028
parentb5f9f8b7438a6a79644d712e267399d618f5d0e1 (diff)
[vulkan] Fine-tuning of frame pacing logic (#3628)
It makes fine adjustments to the frame pacing, ensuring better stability and precision. Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3628 Reviewed-by: crueter <crueter@eden-emu.dev> Reviewed-by: Lizzie <lizzie@eden-emu.dev> Co-authored-by: MaranBr <maranbr@outlook.com> Co-committed-by: MaranBr <maranbr@outlook.com>
-rw-r--r--src/video_core/renderer_vulkan/vk_scheduler.h43
1 files changed, 26 insertions, 17 deletions
diff --git a/src/video_core/renderer_vulkan/vk_scheduler.h b/src/video_core/renderer_vulkan/vk_scheduler.h
index 2913211480..667f136ee6 100644
--- a/src/video_core/renderer_vulkan/vk_scheduler.h
+++ b/src/video_core/renderer_vulkan/vk_scheduler.h
@@ -16,8 +16,8 @@
#include "common/alignment.h"
#include "common/common_types.h"
-#include "common/settings.h"
#include "common/polyfill_thread.h"
+#include "common/settings.h"
#include "video_core/renderer_vulkan/vk_master_semaphore.h"
#include "video_core/vulkan_common/vulkan_wrapper.h"
@@ -114,29 +114,36 @@ public:
/// Waits for the given GPU tick, optionally pacing frames.
void Wait(u64 tick, double target_fps = 0.0) {
+ if (tick > 0) {
+ if (tick >= master_semaphore->CurrentTick()) {
+ Flush();
+ }
+ master_semaphore->Wait(tick);
+ }
if (Settings::values.use_speed_limit.GetValue() && target_fps > 0.0) {
- const auto now = std::chrono::steady_clock::now();
- if (start_time == std::chrono::steady_clock::time_point{} || current_target_fps != target_fps) {
- start_time = now;
+ auto now = std::chrono::steady_clock::now();
+ if (last_target_fps != target_fps) {
+ frame_interval = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(1.0 / target_fps));
+ max_frame_count = static_cast<int>(0.1 * target_fps);
+ last_target_fps = target_fps;
frame_counter = 0;
- current_target_fps = target_fps;
+ start_time = now;
}
frame_counter++;
- std::chrono::duration<double> frame_interval(1.0 / current_target_fps);
auto target_time = start_time + frame_interval * frame_counter;
- if (target_time > now) {
- std::this_thread::sleep_until(target_time);
- } else {
- start_time = now;
+ if (target_time >= now) {
+ auto sleep_time = target_time - now;
+ if (sleep_time > std::chrono::milliseconds(15)) {
+ std::this_thread::sleep_for(sleep_time - std::chrono::milliseconds(1));
+ }
+ while (std::chrono::steady_clock::now() < target_time) {
+ std::this_thread::yield();
+ }
+ } else if (frame_counter > max_frame_count) {
frame_counter = 0;
+ start_time = now;
}
}
- if (tick > 0) {
- if (tick >= master_semaphore->CurrentTick()) {
- Flush();
- }
- master_semaphore->Wait(tick);
- }
}
/// Returns the master timeline semaphore.
@@ -281,9 +288,11 @@ private:
std::condition_variable_any event_cv;
std::jthread worker_thread;
+ std::chrono::steady_clock::duration frame_interval{};
std::chrono::steady_clock::time_point start_time{};
+ double last_target_fps{};
+ u64 max_frame_count{};
u64 frame_counter{};
- double current_target_fps{};
};
} // namespace Vulkan