From bc96de8eb64a4dbc800076e67fa2c28544c91d37 Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Fri, 14 Aug 2026 02:30:55 -0400 Subject: [PATCH] Revert "A quick experiment on frame rate target" --- .../features/settings/model/IntSetting.kt | 1 - .../settings/model/view/SettingsItem.kt | 10 --- .../settings/ui/SettingsFragmentPresenter.kt | 8 +- .../app/src/main/res/values/arrays.xml | 18 ----- .../app/src/main/res/values/strings.xml | 8 -- src/common/settings.cpp | 10 --- src/common/settings.h | 13 ---- .../renderer_vulkan/present/frame_gen.cpp | 75 ++++--------------- .../renderer_vulkan/present/frame_gen.h | 14 +--- .../renderer_vulkan/vk_present_manager.cpp | 2 +- 10 files changed, 16 insertions(+), 143 deletions(-) diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt index e5a4f93fe0..6029a94861 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/IntSetting.kt @@ -21,7 +21,6 @@ enum class IntSetting(override val key: String) : AbstractIntSetting { RENDERER_RESOLUTION("resolution_setup"), RENDERER_FRAME_GEN_MULTIPLIER("frame_gen_multiplier"), RENDERER_FRAME_GEN_QUEUE_TARGET("frame_gen_queue_target"), - RENDERER_FRAME_GEN_TARGET_RATE("frame_gen_target_rate"), RENDERER_FRAME_GEN_FLOW_SCALE("frame_gen_flow_scale"), RENDERER_VSYNC("use_vsync"), RENDERER_SCALING_FILTER("scaling_filter"), diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt index 4195dd0e3d..473f88c9e0 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt @@ -100,7 +100,6 @@ abstract class SettingsItem( BooleanSetting.RENDERER_FRAME_GEN.key, IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key, IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key, - IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key, BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key, IntSetting.RENDERER_FRAME_GEN_FLOW_SCALE.key, BooleanSetting.RENDERER_FRAME_GEN_FP16.key, @@ -641,15 +640,6 @@ abstract class SettingsItem( valuesId = R.array.frameGenMultiplierValues ) ) - put( - SingleChoiceSetting( - IntSetting.RENDERER_FRAME_GEN_TARGET_RATE, - titleId = R.string.frame_gen_target_rate, - descriptionId = R.string.frame_gen_target_rate_description, - choicesId = R.array.frameGenTargetRateNames, - valuesId = R.array.frameGenTargetRateValues - ) - ) put( SingleChoiceSetting( IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET, diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt index 6efc3ca71e..b241d896f7 100644 --- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -125,13 +125,7 @@ class SettingsFragmentPresenter( add(HeaderSetting(R.string.frame_gen)) add(BooleanSetting.RENDERER_FRAME_GEN.key) - add(IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key) - if (IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.getInt( - getNeedsGlobalForKey(IntSetting.RENDERER_FRAME_GEN_TARGET_RATE.key) - ) == 0 - ) { - add(IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key) - } + add(IntSetting.RENDERER_FRAME_GEN_MULTIPLIER.key) add(IntSetting.RENDERER_FRAME_GEN_QUEUE_TARGET.key) add(BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.key) if (!BooleanSetting.RENDERER_FRAME_GEN_FLOW_SCALE_AUTO.getBoolean( diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml index 53dd0436dc..d8ae109e97 100644 --- a/src/android/app/src/main/res/values/arrays.xml +++ b/src/android/app/src/main/res/values/arrays.xml @@ -174,24 +174,6 @@ 4 - - @string/frame_gen_target_rate_off - @string/frame_gen_target_rate_60 - @string/frame_gen_target_rate_90 - @string/frame_gen_target_rate_120 - @string/frame_gen_target_rate_144 - @string/frame_gen_target_rate_165 - - - - 0 - 60 - 90 - 120 - 144 - 165 - - @string/frame_gen_queue_target_0 @string/frame_gen_queue_target_1 diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml index 43d6d56d0d..6d2f2af75f 100644 --- a/src/android/app/src/main/res/values/strings.xml +++ b/src/android/app/src/main/res/values/strings.xml @@ -301,14 +301,6 @@ Frame generation Manage and configure frame generation Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled. - Target frame rate - Aim for a fixed output rate by adjusting the multiplier as the game\'s own frame rate moves. Pick a rate your display can actually present. - Off (use fixed multiplier) - 60 fps - 90 fps - 120 fps - 144 fps - 165 fps Frame multiplier How many frames to display for each rendered frame. Higher values cost proportionally more GPU time. Asking for more than your display can present will slow emulation down. 2x diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 6cc976fe51..1f747c44b1 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -392,16 +392,6 @@ size_t FrameGenGenerations() { return FrameGenMultiplier() - 1; } -size_t FrameGenMaxGenerations() { - if (!values.frame_gen.GetValue()) { - return 0; - } - if (values.frame_gen_target_rate.GetValue() != 0) { - return MAX_FRAME_GEN_MULTIPLIER - 1; - } - return FrameGenMultiplier() - 1; -} - void RestoreGlobalState(bool is_powered_on) { // If a game is running, DO NOT restore the global settings state if (is_powered_on) { diff --git a/src/common/settings.h b/src/common/settings.h index 9a8384c5db..730dbc0e02 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -423,17 +423,6 @@ struct Values { true, &frame_gen}; - SwitchableSetting frame_gen_target_rate{linkage, - 0, - 0, - 240, - "frame_gen_target_rate", - Category::Renderer, - Specialization::Countable, - true, - false, - &frame_gen}; - SwitchableSetting frame_gen_queue_target{linkage, 1, 0, @@ -945,8 +934,6 @@ constexpr u32 MAX_FRAME_GEN_MULTIPLIER = 4; [[nodiscard]] size_t FrameGenGenerations(); -[[nodiscard]] size_t FrameGenMaxGenerations(); - bool getDebugKnobAt(u8 i); void UpdateGPUAccuracy(); diff --git a/src/video_core/renderer_vulkan/present/frame_gen.cpp b/src/video_core/renderer_vulkan/present/frame_gen.cpp index 20cf2d35ab..ab1f6c50d4 100644 --- a/src/video_core/renderer_vulkan/present/frame_gen.cpp +++ b/src/video_core/renderer_vulkan/present/frame_gen.cpp @@ -43,8 +43,9 @@ constexpr u64 LSFG_REQUIRED_FRAMES = 2; return std::clamp(stepped, 0.25f, 1.0f); } -constexpr f32 BASE_RATE_SMOOTHING = 0.1f; -constexpr u32 GENERATION_CHANGE_VOTES = 30; +[[nodiscard]] size_t ConfiguredGenerations() { + return Settings::FrameGenGenerations(); +} bool IsBlueFirst(VkFormat format) { return format == VK_FORMAT_B8G8R8A8_UNORM || format == VK_FORMAT_B8G8R8A8_SRGB; @@ -196,68 +197,11 @@ FrameGen::FrameGen(MemoryAllocator& memory_allocator_, Scheduler& scheduler_) FrameGen::~FrameGen() = default; -void FrameGen::UpdateBaseRate() { - const auto now = Clock::now(); - if (last_process_time.time_since_epoch().count() != 0) { - const f32 seconds = std::chrono::duration(now - last_process_time).count(); - const f32 rate = seconds > 0.0f ? 1.0f / seconds : 0.0f; - if (rate >= 1.0f && rate <= 1000.0f) { - smoothed_base_rate = smoothed_base_rate <= 0.0f - ? rate - : smoothed_base_rate + - (rate - smoothed_base_rate) * BASE_RATE_SMOOTHING; - } - } - last_process_time = now; -} - -size_t FrameGen::DesiredGenerations() const { - if (!Settings::values.frame_gen.GetValue()) { - return 0; - } - - const u32 target = Settings::values.frame_gen_target_rate.GetValue(); - if (target == 0) { - return Settings::FrameGenGenerations(); - } - if (smoothed_base_rate <= 1.0f) { - return 0; - } - - const size_t multiplier = static_cast(static_cast(target) / smoothed_base_rate); - return std::clamp(multiplier, 1, LSFG_MAX_GENERATIONS + 1) - 1; -} - -void FrameGen::UpdateGenerationCount() { - const size_t desired = DesiredGenerations(); - if (desired == stable_generations) { - pending_generation_votes = 0; - return; - } - - if (desired != pending_generations) { - pending_generations = desired; - pending_generation_votes = 1; - return; - } - - if (++pending_generation_votes >= GENERATION_CHANGE_VOTES) { - stable_generations = desired; - pending_generation_votes = 0; - } -} - -size_t FrameGen::WantedGenerations() { - UpdateBaseRate(); - UpdateGenerationCount(); - return unavailable ? 0 : stable_generations; -} - void FrameGen::Process(const Device& device, Frame* frame, VkFormat format, VkExtent2D guest_extent, bool generate) { generated = false; - if (unavailable || !Settings::values.frame_gen.GetValue()) { + if (unavailable || ConfiguredGenerations() == 0) { if (chain) { scheduler.Finish(); chain.reset(); @@ -290,8 +234,8 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format, VkEx const u64 count = frame_count++; last_count = count; - last_generations = stable_generations; - generated = generate && last_generations > 0 && count + 1 >= LSFG_REQUIRED_FRAMES; + last_generations = ConfiguredGenerations(); + generated = generate && count + 1 >= LSFG_REQUIRED_FRAMES; scheduler.RequestOutsideRenderPassOperationContext(); scheduler.Record([this, source = *frame->image, extent, count, @@ -311,6 +255,13 @@ void FrameGen::Process(const Device& device, Frame* frame, VkFormat format, VkEx } } +size_t FrameGen::WantedGenerations() const { + if (unavailable) { + return 0; + } + return ConfiguredGenerations(); +} + size_t FrameGen::GeneratedFrameCount() const { return generated ? last_generations : 0; } diff --git a/src/video_core/renderer_vulkan/present/frame_gen.h b/src/video_core/renderer_vulkan/present/frame_gen.h index 66c346503d..5f1e3e4135 100644 --- a/src/video_core/renderer_vulkan/present/frame_gen.h +++ b/src/video_core/renderer_vulkan/present/frame_gen.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include "common/common_types.h" @@ -25,19 +24,14 @@ public: void Process(const Device& device, Frame* frame, VkFormat format, VkExtent2D guest_extent, bool generate); - [[nodiscard]] size_t WantedGenerations(); + [[nodiscard]] size_t WantedGenerations() const; [[nodiscard]] size_t GeneratedFrameCount() const; void GenerateInto(const Device& device, Frame* destination, size_t generation); private: - using Clock = std::chrono::steady_clock; - void Rebuild(const Device& device, VkExtent2D extent, VkFormat format, f32 flow_scale); - void UpdateBaseRate(); - void UpdateGenerationCount(); - [[nodiscard]] size_t DesiredGenerations() const; void DumpDebugImages(u64 count); MemoryAllocator& memory_allocator; @@ -52,12 +46,6 @@ private: u64 frame_count{}; u64 last_count{}; size_t last_generations{}; - - Clock::time_point last_process_time{}; - f32 smoothed_base_rate{}; - size_t stable_generations{}; - size_t pending_generations{}; - u32 pending_generation_votes{}; bool generated{}; bool unavailable{}; bool dumped{}; diff --git a/src/video_core/renderer_vulkan/vk_present_manager.cpp b/src/video_core/renderer_vulkan/vk_present_manager.cpp index 0c51fc9e63..8924241562 100644 --- a/src/video_core/renderer_vulkan/vk_present_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_present_manager.cpp @@ -351,7 +351,7 @@ void PresentManager::SetImageCount() { // We cannot have more than 7 images in flight at any given time. // FRAMES_IN_FLIGHT is 8, and the cache TICKS_TO_DESTROY is 8. // Mali drivers will give us 6. - const size_t generations = Settings::FrameGenMaxGenerations(); + const size_t generations = Settings::FrameGenGenerations(); const size_t queued_composites = Settings::values.frame_gen_queue_target.GetValue() + 1; image_count = std::clamp((generations + 1) * queued_composites, swapchain.GetImageCount(),