Revert "A quick experiment on frame rate target"

This commit is contained in:
CamilleLaVey
2026-08-14 02:30:55 -04:00
parent 417d80fc42
commit bc96de8eb6
10 changed files with 16 additions and 143 deletions
@@ -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"),
@@ -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,
@@ -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(
@@ -174,24 +174,6 @@
<item>4</item>
</integer-array>
<string-array name="frameGenTargetRateNames">
<item>@string/frame_gen_target_rate_off</item>
<item>@string/frame_gen_target_rate_60</item>
<item>@string/frame_gen_target_rate_90</item>
<item>@string/frame_gen_target_rate_120</item>
<item>@string/frame_gen_target_rate_144</item>
<item>@string/frame_gen_target_rate_165</item>
</string-array>
<integer-array name="frameGenTargetRateValues">
<item>0</item>
<item>60</item>
<item>90</item>
<item>120</item>
<item>144</item>
<item>165</item>
</integer-array>
<string-array name="frameGenQueueTargetNames">
<item>@string/frame_gen_queue_target_0</item>
<item>@string/frame_gen_queue_target_1</item>
@@ -301,14 +301,6 @@
<string name="frame_gen">Frame generation</string>
<string name="frame_gen_submenu_description">Manage and configure frame generation</string>
<string name="frame_gen_description">Insert interpolated frames between rendered ones using Lossless Scaling. Forces FIFO presentation while enabled.</string>
<string name="frame_gen_target_rate">Target frame rate</string>
<string name="frame_gen_target_rate_description">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.</string>
<string name="frame_gen_target_rate_off">Off (use fixed multiplier)</string>
<string name="frame_gen_target_rate_60">60 fps</string>
<string name="frame_gen_target_rate_90">90 fps</string>
<string name="frame_gen_target_rate_120">120 fps</string>
<string name="frame_gen_target_rate_144">144 fps</string>
<string name="frame_gen_target_rate_165">165 fps</string>
<string name="frame_gen_multiplier">Frame multiplier</string>
<string name="frame_gen_multiplier_description">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.</string>
<string name="frame_gen_multiplier_2x">2x</string>
-10
View File
@@ -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) {
-13
View File
@@ -423,17 +423,6 @@ struct Values {
true,
&frame_gen};
SwitchableSetting<u32, true> frame_gen_target_rate{linkage,
0,
0,
240,
"frame_gen_target_rate",
Category::Renderer,
Specialization::Countable,
true,
false,
&frame_gen};
SwitchableSetting<u32, true> 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();
@@ -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<f32>(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<size_t>(static_cast<f32>(target) / smoothed_base_rate);
return std::clamp<size_t>(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;
}
@@ -3,7 +3,6 @@
#pragma once
#include <chrono>
#include <optional>
#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{};
@@ -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<size_t>((generations + 1) * queued_composites, swapchain.GetImageCount(),