diff --git a/config.def.h b/config.def.h index d99c529eb9..22350ae7f1 100644 --- a/config.def.h +++ b/config.def.h @@ -411,6 +411,8 @@ static const bool disable_composition = false; /* Video VSYNC (recommended) */ static const bool vsync = true; +static const unsigned max_swapchain_images = 3; + /* Attempts to hard-synchronize CPU and GPU. * Can reduce latency at cost of performance. */ static const bool hard_sync = false; diff --git a/configuration.c b/configuration.c index 2f774a4ea9..57fa933edb 100644 --- a/configuration.c +++ b/configuration.c @@ -495,6 +495,7 @@ static void config_set_defaults(void) settings->video.fullscreen_y = fullscreen_y; settings->video.disable_composition = disable_composition; settings->video.vsync = vsync; + settings->video.max_swapchain_images = max_swapchain_images; settings->video.hard_sync = hard_sync; settings->video.hard_sync_frames = hard_sync_frames; settings->video.frame_delay = frame_delay; @@ -1291,6 +1292,7 @@ static bool config_load_file(const char *path, bool set_defaults) CONFIG_GET_INT_BASE (conf, settings, video.monitor_index, "video_monitor_index"); CONFIG_GET_BOOL_BASE(conf, settings, video.disable_composition, "video_disable_composition"); CONFIG_GET_BOOL_BASE(conf, settings, video.vsync, "video_vsync"); + CONFIG_GET_INT_BASE(conf, settings, video.max_swapchain_images, "video_max_swapchain_images"); CONFIG_GET_BOOL_BASE(conf, settings, video.hard_sync, "video_hard_sync"); #ifdef HAVE_MENU @@ -2658,6 +2660,8 @@ bool config_save_file(const char *path) config_set_bool(conf, "video_vsync", settings->video.vsync); + config_set_int(conf, "video_max_swapchain_images", + settings->video.max_swapchain_images); config_set_bool(conf, "video_hard_sync", settings->video.hard_sync); config_set_int(conf, "video_hard_sync_frames", settings->video.hard_sync_frames); diff --git a/configuration.h b/configuration.h index 95fa5e9571..2cfbcb1fb9 100644 --- a/configuration.h +++ b/configuration.h @@ -55,6 +55,7 @@ typedef struct settings bool vsync; bool hard_sync; bool black_frame_insertion; + unsigned max_swapchain_images; unsigned swap_interval; unsigned hard_sync_frames; unsigned frame_delay; diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index a632d01af4..c4a07b0ebd 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -245,6 +245,7 @@ static bool gfx_ctx_drm_queue_flip(void) static void gfx_ctx_drm_swap_buffers(void *data) { gfx_ctx_drm_data_t *drm = (gfx_ctx_drm_data_t*)data; + settings_t *settings = config_get_ptr(); switch (drm_api) { @@ -269,12 +270,11 @@ static void gfx_ctx_drm_swap_buffers(void *data) waiting_for_flip = gfx_ctx_drm_queue_flip(); - if (gbm_surface_has_free_buffers(g_gbm_surface)) + /* Triple-buffered page flips */ + if (settings->video.max_swapchain_images >= 3 && + gbm_surface_has_free_buffers(g_gbm_surface)) return; - /* We have to wait for this flip to finish. - * This shouldn't happen as we have triple buffered page-flips. */ - RARCH_WARN("[KMS]: Triple buffering is not working correctly ...\n"); gfx_ctx_drm_wait_flip(true); } diff --git a/intl/msg_hash_us.c b/intl/msg_hash_us.c index e77dfb4a55..71affb7cfb 100644 --- a/intl/msg_hash_us.c +++ b/intl/msg_hash_us.c @@ -1105,6 +1105,8 @@ static const char *menu_hash_to_str_us_label_enum(enum msg_hash_enums msg) { switch (msg) { + case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES: + return "video_max_swapchain_images"; case MENU_ENUM_LABEL_CORE_SETTINGS: return "core_settings"; case MENU_ENUM_LABEL_CB_MENU_WALLPAPER: @@ -1997,6 +1999,8 @@ const char *msg_hash_to_str_us(enum msg_hash_enums msg) return "Compiled against API"; case MSG_FAILED_TO_LOAD: return "Failed to load"; + case MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES: + return "Max swapchain images"; case MSG_ERROR_LIBRETRO_CORE_REQUIRES_CONTENT: return "Libretro core requires content, but nothing was provided."; case MSG_CONTENT_LOADING_SKIPPED_IMPLEMENTATION_WILL_DO_IT: diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 6c8db2bfd5..4496b7580e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4068,6 +4068,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_VSYNC, PARSE_ONLY_BOOL, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, + PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL, PARSE_ONLY_UINT, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 136293faab..048f3d9bce 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -5247,6 +5247,21 @@ static bool setting_append_list( ); menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_VIDEO_VSYNC); + CONFIG_UINT( + list, list_info, + &settings->video.max_swapchain_images, + msg_hash_to_str(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES), + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES), + max_swapchain_images, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 1, 4, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO|SD_FLAG_ADVANCED); + menu_settings_list_current_add_enum_idx(list, list_info, MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES); + CONFIG_UINT( list, list_info, &settings->video.swap_interval, diff --git a/msg_hash.h b/msg_hash.h index b09fbe74ef..afb66efe87 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -323,6 +323,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VIDEO_FILTER_FLICKER, MENU_ENUM_LABEL_VIDEO_SOFT_FILTER, MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL, + MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES, MENU_ENUM_LABEL_VIDEO_GPU_SCREENSHOT, MENU_ENUM_LABEL_VIDEO_FULLSCREEN, MENU_ENUM_LABEL_VIDEO_BLACK_FRAME_INSERTION, @@ -367,6 +368,7 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_VIDEO_VSYNC, MENU_ENUM_LABEL_VALUE_VIDEO_HARD_SYNC, MENU_ENUM_LABEL_VALUE_VIDEO_SWAP_INTERVAL, + MENU_ENUM_LABEL_VALUE_VIDEO_MAX_SWAPCHAIN_IMAGES, MENU_ENUM_LABEL_VALUE_VIDEO_GPU_SCREENSHOT, MENU_ENUM_LABEL_VALUE_VIDEO_FULLSCREEN, MENU_ENUM_LABEL_VALUE_VIDEO_FORCE_ASPECT, diff --git a/retroarch.cfg b/retroarch.cfg index eed7864bbb..fe133273db 100644 --- a/retroarch.cfg +++ b/retroarch.cfg @@ -141,6 +141,9 @@ # Video vsync. # video_vsync = true +# Video swapchain images. +# video_max_swapchain_images = 3 + # Forcibly disable sRGB FBO support. Some Intel OpenGL drivers on Windows # have video problems with sRGB FBO support enabled. # video_force_srgb_disable = false