mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-16 21:33:01 +00:00
Revert "A quick experiment on frame rate target"
This commit is contained in:
@@ -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"),
|
||||
|
||||
-10
@@ -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,
|
||||
|
||||
+1
-7
@@ -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>
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user