1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 18:53:28 +01:00

rsx: Improve frame-limiter (#7723)

* rsx: Improve frame-limiter accuracy

* lv2: Improve lv2_obj::wait_timeout response time for aborting threads

* rsx: Make stretch to display area setting dynamic

* rsx: Redefine 'auto' frame limiter to obey vblank rate

* rsx: Make frame limiter setting dynamic

* rsx: Make frame-limiter compatible with dynamic changes
This commit is contained in:
Eladash 2020-03-08 00:11:35 +02:00 committed by GitHub
parent deb6bd3e25
commit 892f74d762
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 29 additions and 22 deletions

View File

@ -586,7 +586,6 @@ void cellGcmSetSecondVFrequency(u32 freq)
switch (freq)
{
case CELL_GCM_DISPLAY_FREQUENCY_59_94HZ:
render->fps_limit = 59.94;
break;
case CELL_GCM_DISPLAY_FREQUENCY_SCANOUT:
cellGcmSys.todo("Unimplemented display frequency: Scanout");

View File

@ -251,13 +251,19 @@ public:
}
}
template<bool is_usleep = false>
template<bool is_usleep = false, bool scale = true>
static bool wait_timeout(u64 usec, cpu_thread* const cpu = {})
{
static_assert(UINT64_MAX / cond_variable::max_timeout >= 100, "max timeout is not valid for scaling");
// Clamp and scale the result
usec = std::min<u64>(std::min<u64>(usec, UINT64_MAX / 100) * 100 / g_cfg.core.clocks_scale, cond_variable::max_timeout);
if constexpr (scale)
{
// Scale time
usec = std::min<u64>(usec, UINT64_MAX / 100) * 100 / g_cfg.core.clocks_scale;
}
// Clamp
usec = std::min<u64>(usec, cond_variable::max_timeout);
extern u64 get_system_time();
@ -301,7 +307,7 @@ public:
}
}
if (Emu.IsStopped())
if (thread_ctrl::state() == thread_state::aborting)
{
return false;
}

View File

@ -2654,33 +2654,38 @@ namespace rsx
case frame_limit_type::_50: limit = 50.; break;
case frame_limit_type::_60: limit = 60.; break;
case frame_limit_type::_30: limit = 30.; break;
case frame_limit_type::_auto: limit = fps_limit; break; // TODO
case frame_limit_type::_auto: limit = g_cfg.video.vblank_rate; break; // TODO
default:
break;
}
if (limit)
{
const u64 time = get_system_time() - Emu.GetPauseTime() - start_rsx_time;
const u64 time = get_system_time() - Emu.GetPauseTime();
const u64 needed_us = static_cast<u64>(1000000 / limit);
if (int_flip_index == 0)
{
start_rsx_time = time;
target_rsx_flip_time = time;
}
else
{
// Convert limit to expected time value
double expected = int_flip_index * 1000000. / limit;
while (time >= expected + 1000000. / limit)
do
{
expected = int_flip_index++ * 1000000. / limit;
target_rsx_flip_time += needed_us;
}
while (time >= target_rsx_flip_time + needed_us);
if (expected > time + 1000)
if (target_rsx_flip_time > time + 1000)
{
const auto delay_us = static_cast<s64>(expected - time);
std::this_thread::sleep_for(std::chrono::milliseconds{ delay_us / 1000 });
const auto delay_us = target_rsx_flip_time - time;
lv2_obj::wait_timeout<false, false>(delay_us);
if (thread_ctrl::state() == thread_state::aborting)
{
return;
}
performance_counters.idle_time += delay_us;
}
}

View File

@ -710,10 +710,7 @@ namespace rsx
void get_current_fragment_program(const std::array<std::unique_ptr<rsx::sampled_image_descriptor_base>, rsx::limits::fragment_textures_count>& sampler_descriptors);
public:
double fps_limit = 59.94;
public:
u64 start_rsx_time = 0;
u64 target_rsx_flip_time = 0;
u64 int_flip_index = 0;
u64 last_flip_time = 0;
vm::ptr<void(u32)> flip_handler = vm::null;

View File

@ -96,7 +96,7 @@ struct cfg_root : cfg::node
cfg::_enum<video_resolution> resolution{ this, "Resolution", video_resolution::_720 };
cfg::_enum<video_aspect> aspect_ratio{ this, "Aspect ratio", video_aspect::_16_9 };
cfg::_enum<frame_limit_type> frame_limit{ this, "Frame limit", frame_limit_type::none };
cfg::_enum<frame_limit_type> frame_limit{ this, "Frame limit", frame_limit_type::none, true };
cfg::_enum<msaa_level> antialiasing_level{ this, "MSAA", msaa_level::_auto };
cfg::_bool write_color_buffers{ this, "Write Color Buffers" };
@ -109,7 +109,7 @@ struct cfg_root : cfg::node
cfg::_bool overlay{ this, "Debug overlay" };
cfg::_bool gl_legacy_buffers{ this, "Use Legacy OpenGL Buffers" };
cfg::_bool use_gpu_texture_scaling{ this, "Use GPU texture scaling", false };
cfg::_bool stretch_to_display_area{ this, "Stretch To Display Area" };
cfg::_bool stretch_to_display_area{ this, "Stretch To Display Area", false, true };
cfg::_bool force_high_precision_z_buffer{ this, "Force High Precision Z buffer" };
cfg::_bool strict_rendering_mode{ this, "Strict Rendering Mode" };
cfg::_bool disable_zcull_queries{ this, "Disable ZCull Occlusion Queries", false };