Fix frame pacing when switching games

This commit is contained in:
MaranBr 2026-02-09 11:03:25 -04:00 committed by crueter
parent d6f6885e21
commit 114cd4e703
7 changed files with 22 additions and 11 deletions

View File

@ -531,7 +531,7 @@
</integer-array>
<string-array name="framePacingModeNames">
<item>@string/frame_pacing_mode_default</item>
<item>@string/frame_pacing_mode_target_Auto</item>
<item>@string/frame_pacing_mode_target_30</item>
<item>@string/frame_pacing_mode_target_60</item>
<item>@string/frame_pacing_mode_target_120</item>

View File

@ -1026,7 +1026,7 @@
<string name="dma_accuracy_safe">Safe</string>
<!-- Frame Pacing Mode -->
<string name="frame_pacing_mode_default">Default</string>
<string name="frame_pacing_mode_target_Auto">Auto</string>
<string name="frame_pacing_mode_target_30">30 FPS</string>
<string name="frame_pacing_mode_target_60">60 FPS</string>
<string name="frame_pacing_mode_target_120">120 FPS</string>

View File

@ -435,8 +435,8 @@ struct Values {
Category::RendererAdvanced};
SwitchableSetting<FramePacingMode, true> frame_pacing_mode{linkage,
FramePacingMode::Default,
FramePacingMode::Default,
FramePacingMode::Target_Auto,
FramePacingMode::Target_Auto,
FramePacingMode::Target_120,
"frame_pacing_mode",
Category::RendererAdvanced};

View File

@ -129,7 +129,7 @@ ENUM(TimeZone, Auto, Default, Cet, Cst6Cdt, Cuba, Eet, Egypt, Eire, Est, Est5Edt
ENUM(AnisotropyMode, Automatic, Default, X2, X4, X8, X16, X32, X64, None);
ENUM(AstcDecodeMode, Cpu, Gpu, CpuAsynchronous);
ENUM(AstcRecompression, Uncompressed, Bc1, Bc3);
ENUM(FramePacingMode, Default, Target_30, Target_60, Target_120);
ENUM(FramePacingMode, Target_Auto, Target_30, Target_60, Target_120);
ENUM(VSyncMode, Immediate, Mailbox, Fifo, FifoRelaxed);
ENUM(VramUsageMode, Conservative, Aggressive);
ENUM(RendererBackend, OpenGL_GLSL, Vulkan, Null, OpenGL_GLASM, OpenGL_SPIRV);

View File

@ -501,7 +501,7 @@ std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QObject* parent)
}});
translations->insert({Settings::EnumMetadata<Settings::FramePacingMode>::Index(),
{
PAIR(FramePacingMode, Default, tr("Default")),
PAIR(FramePacingMode, Target_Auto, tr("Auto")),
PAIR(FramePacingMode, Target_30, tr("30 FPS")),
PAIR(FramePacingMode, Target_60, tr("60 FPS")),
PAIR(FramePacingMode, Target_120, tr("120 FPS")),

View File

@ -125,10 +125,12 @@ public:
if (master_semaphore->CurrentTick() >= tick) {
return;
}
static auto next_frame_time = std::chrono::steady_clock::now();
auto frame_duration = std::chrono::duration<double>(1.0 / target_fps);
next_frame_time += std::chrono::duration_cast<std::chrono::steady_clock::duration>(frame_duration);
auto now = std::chrono::steady_clock::now();
const auto frame_duration = std::chrono::duration_cast<std::chrono::steady_clock::duration>(std::chrono::duration<double>(1.0 / target_fps));
const auto now = std::chrono::steady_clock::now();
if (next_frame_time == std::chrono::steady_clock::time_point{}) {
next_frame_time = now;
}
next_frame_time += frame_duration;
if (next_frame_time > now) {
std::this_thread::sleep_until(next_frame_time);
} else {
@ -136,6 +138,10 @@ public:
}
}
void ResetFramePacing() {
next_frame_time = std::chrono::steady_clock::now();
}
/// Returns the master timeline semaphore.
[[nodiscard]] MasterSemaphore& GetMasterSemaphore() const noexcept {
return *master_semaphore;
@ -277,6 +283,8 @@ private:
std::mutex queue_mutex;
std::condition_variable_any event_cv;
std::jthread worker_thread;
std::chrono::steady_clock::time_point next_frame_time{};
};
} // namespace Vulkan

View File

@ -146,6 +146,9 @@ void Swapchain::Create(
{
is_outdated = false;
is_suboptimal = false;
scheduler.ResetFramePacing();
width = width_;
height = height_;
#ifdef ANDROID
@ -198,7 +201,7 @@ bool Swapchain::AcquireNextImage() {
scheduler.Wait(resource_ticks[image_index]);
} else {
switch (Settings::values.frame_pacing_mode.GetValue()) {
case Settings::FramePacingMode::Default:
case Settings::FramePacingMode::Target_Auto:
scheduler.Wait(resource_ticks[image_index]);
break;
case Settings::FramePacingMode::Target_30: