mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-23 03:02:53 +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:
parent
deb6bd3e25
commit
892f74d762
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 };
|
||||
|
Loading…
Reference in New Issue
Block a user