High Hz Synchronization (#15798)

* High Hz Synchronization

Makes adjustment to driver_adjust_system_rates and related functions to handle Hz skew adjustment for high refresh rates better, especially when using effective refresh modifiers like swap interval or BFI.

* Reorder for Build Fix

Reorder declaration for build fix
This commit is contained in:
Ophidon 2023-10-14 09:57:40 -04:00 committed by GitHub
parent 777d96d20a
commit ce6a00b495
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 44 additions and 13 deletions

View File

@ -13346,6 +13346,8 @@ static bool setting_append_list(
general_read_handler); general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
menu_settings_list_current_add_range(list, list_info, 0, 5, 1, true, true); menu_settings_list_current_add_range(list, list_info, 0, 5, 1, true, true);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
} }
} }
#endif #endif

View File

@ -601,12 +601,24 @@ static float audio_driver_monitor_adjust_system_rates(
double input_fps, double input_fps,
float video_refresh_rate, float video_refresh_rate,
unsigned video_swap_interval, unsigned video_swap_interval,
unsigned black_frame_insertion,
float audio_max_timing_skew) float audio_max_timing_skew)
{ {
float inp_sample_rate = input_sample_rate; float inp_sample_rate = input_sample_rate;
float target_video_sync_rate = video_refresh_rate
/ (float)video_swap_interval; /* This much like the auto swap interval algorithm and will
float timing_skew = * find the correct desired target rate the majority of sane
* cases. Any failures should be no worse than the previous
* very incomplete high hz skew adjustments. */
float refresh_ratio = video_refresh_rate/input_fps;
unsigned refresh_closest_multiple = (unsigned)(refresh_ratio + 0.5f);
float target_video_sync_rate = video_refresh_rate;
float timing_skew = 0.0f;
if (refresh_closest_multiple > 1)
target_video_sync_rate /= (((float)black_frame_insertion + 1.0f) * (float)video_swap_interval);
timing_skew =
fabs(1.0f - input_fps / target_video_sync_rate); fabs(1.0f - input_fps / target_video_sync_rate);
if (timing_skew <= audio_max_timing_skew) if (timing_skew <= audio_max_timing_skew)
return (inp_sample_rate * target_video_sync_rate / input_fps); return (inp_sample_rate * target_video_sync_rate / input_fps);
@ -620,18 +632,23 @@ static bool video_driver_monitor_adjust_system_rates(
bool vrr_runloop_enable, bool vrr_runloop_enable,
float audio_max_timing_skew, float audio_max_timing_skew,
unsigned video_swap_interval, unsigned video_swap_interval,
unsigned black_frame_insertion,
double input_fps) double input_fps)
{ {
float target_video_sync_rate = timing_skew_hz; float target_video_sync_rate = timing_skew_hz;
/* Divide target rate only when using Auto interval */ /* Same concept as for audio driver adjust. */
if (_video_swap_interval == 0) float refresh_ratio = target_video_sync_rate/input_fps;
target_video_sync_rate /= (float)video_swap_interval; unsigned refresh_closest_multiple = (unsigned)(refresh_ratio + 0.5f);
float timing_skew = 0.0f;
if (refresh_closest_multiple > 1)
target_video_sync_rate /= (((float)black_frame_insertion + 1.0f) * (float)video_swap_interval);
if (!vrr_runloop_enable) if (!vrr_runloop_enable)
{ {
float timing_skew = fabs( timing_skew =
1.0f - input_fps / target_video_sync_rate); fabs(1.0f - input_fps / target_video_sync_rate);
/* We don't want to adjust pitch too much. If we have extreme cases, /* We don't want to adjust pitch too much. If we have extreme cases,
* just don't readjust at all. */ * just don't readjust at all. */
if (timing_skew <= audio_max_timing_skew) if (timing_skew <= audio_max_timing_skew)
@ -652,7 +669,8 @@ static void driver_adjust_system_rates(
float video_refresh_rate, float video_refresh_rate,
float audio_max_timing_skew, float audio_max_timing_skew,
bool video_adaptive_vsync, bool video_adaptive_vsync,
unsigned video_swap_interval) unsigned video_swap_interval,
unsigned black_frame_insertion)
{ {
struct retro_system_av_info *av_info = &video_st->av_info; struct retro_system_av_info *av_info = &video_st->av_info;
const struct retro_system_timing *info = const struct retro_system_timing *info =
@ -666,6 +684,7 @@ static void driver_adjust_system_rates(
vrr_runloop_enable, vrr_runloop_enable,
(video_st->flags & VIDEO_FLAG_CRT_SWITCHING_ACTIVE) ? true : false, (video_st->flags & VIDEO_FLAG_CRT_SWITCHING_ACTIVE) ? true : false,
video_swap_interval, video_swap_interval,
black_frame_insertion,
audio_max_timing_skew, audio_max_timing_skew,
video_refresh_rate, video_refresh_rate,
input_fps); input_fps);
@ -684,6 +703,7 @@ static void driver_adjust_system_rates(
input_fps, input_fps,
video_refresh_rate, video_refresh_rate,
video_swap_interval, video_swap_interval,
black_frame_insertion,
audio_max_timing_skew); audio_max_timing_skew);
RARCH_LOG("[Audio]: Set audio input rate to: %.2f Hz.\n", RARCH_LOG("[Audio]: Set audio input rate to: %.2f Hz.\n",
@ -707,6 +727,7 @@ static void driver_adjust_system_rates(
vrr_runloop_enable, vrr_runloop_enable,
audio_max_timing_skew, audio_max_timing_skew,
video_swap_interval, video_swap_interval,
black_frame_insertion,
input_fps)) input_fps))
{ {
/* We won't be able to do VSync reliably /* We won't be able to do VSync reliably
@ -826,7 +847,8 @@ void drivers_init(
settings->floats.video_refresh_rate, settings->floats.video_refresh_rate,
settings->floats.audio_max_timing_skew, settings->floats.audio_max_timing_skew,
settings->bools.video_adaptive_vsync, settings->bools.video_adaptive_vsync,
settings->uints.video_swap_interval settings->uints.video_swap_interval,
settings->uints.video_black_frame_insertion
); );
/* Initialize video driver */ /* Initialize video driver */
@ -1260,6 +1282,8 @@ bool driver_ctl(enum driver_ctl_state state, void *data)
float audio_max_timing_skew = settings->floats.audio_max_timing_skew; float audio_max_timing_skew = settings->floats.audio_max_timing_skew;
bool video_adaptive_vsync = settings->bools.video_adaptive_vsync; bool video_adaptive_vsync = settings->bools.video_adaptive_vsync;
unsigned video_swap_interval = settings->uints.video_swap_interval; unsigned video_swap_interval = settings->uints.video_swap_interval;
unsigned
black_frame_insertion = settings->uints.video_black_frame_insertion;
video_monitor_set_refresh_rate(*hz); video_monitor_set_refresh_rate(*hz);
@ -1273,7 +1297,8 @@ bool driver_ctl(enum driver_ctl_state state, void *data)
video_refresh_rate, video_refresh_rate,
audio_max_timing_skew, audio_max_timing_skew,
video_adaptive_vsync, video_adaptive_vsync,
video_swap_interval video_swap_interval,
black_frame_insertion
); );
} }
break; break;

View File

@ -4399,6 +4399,7 @@ void runloop_set_video_swap_interval(
bool vrr_runloop_enable, bool vrr_runloop_enable,
bool crt_switching_active, bool crt_switching_active,
unsigned swap_interval_config, unsigned swap_interval_config,
unsigned black_frame_insertion,
float audio_max_timing_skew, float audio_max_timing_skew,
float video_refresh_rate, float video_refresh_rate,
double input_fps) double input_fps)
@ -4425,11 +4426,13 @@ void runloop_set_video_swap_interval(
* > If core fps is higher than display refresh rate, * > If core fps is higher than display refresh rate,
* set swap interval to 1 * set swap interval to 1
* > If core fps or display refresh rate are zero, * > If core fps or display refresh rate are zero,
* set swap interval to 1 */ * set swap interval to 1
* > If BFI is active set swap interval to 1 */
if ( (vrr_runloop_enable) if ( (vrr_runloop_enable)
|| (core_hz > timing_hz) || (core_hz > timing_hz)
|| (core_hz <= 0.0f) || (core_hz <= 0.0f)
|| (timing_hz <= 0.0f)) || (timing_hz <= 0.0f)
|| (black_frame_insertion))
{ {
runloop_st->video_swap_interval_auto = 1; runloop_st->video_swap_interval_auto = 1;
return; return;

View File

@ -396,6 +396,7 @@ void runloop_set_video_swap_interval(
bool vrr_runloop_enable, bool vrr_runloop_enable,
bool crt_switching_active, bool crt_switching_active,
unsigned swap_interval_config, unsigned swap_interval_config,
unsigned black_frame_insertion,
float audio_max_timing_skew, float audio_max_timing_skew,
float video_refresh_rate, float video_refresh_rate,
double input_fps); double input_fps);