(D3D11/12) Make waitable swapchains optional (#14074)

This commit is contained in:
sonninnos 2022-06-19 22:25:37 +03:00 committed by GitHub
parent e954a69708
commit a0bfdcce3b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 82 additions and 13 deletions

View file

@ -339,7 +339,13 @@
#define DEFAULT_MAX_SWAPCHAIN_IMAGES 3
/* D3D1x specific */
#if defined(__WINRT__) || defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP
#define DEFAULT_WAITABLE_SWAPCHAINS false
#else
#define DEFAULT_WAITABLE_SWAPCHAINS true
#endif
#define DEFAULT_MAX_FRAME_LATENCY 1
#define MAXIMUM_MAX_FRAME_LATENCY 4
/* GL specific */
#define DEFAULT_ADAPTIVE_VSYNC false

View file

@ -1698,6 +1698,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("video_vsync", &settings->bools.video_vsync, true, DEFAULT_VSYNC, false);
SETTING_BOOL("video_adaptive_vsync", &settings->bools.video_adaptive_vsync, true, DEFAULT_ADAPTIVE_VSYNC, false);
SETTING_BOOL("video_hard_sync", &settings->bools.video_hard_sync, true, DEFAULT_HARD_SYNC, false);
SETTING_BOOL("video_waitable_swapchains", &settings->bools.video_waitable_swapchains, true, DEFAULT_WAITABLE_SWAPCHAINS, false);
SETTING_BOOL("video_disable_composition", &settings->bools.video_disable_composition, true, DEFAULT_DISABLE_COMPOSITION, false);
SETTING_BOOL("pause_nonactive", &settings->bools.pause_nonactive, true, DEFAULT_PAUSE_NONACTIVE, false);
SETTING_BOOL("video_gpu_screenshot", &settings->bools.video_gpu_screenshot, true, DEFAULT_GPU_SCREENSHOT, false);

View file

@ -521,6 +521,7 @@ typedef struct settings
bool video_vsync;
bool video_adaptive_vsync;
bool video_hard_sync;
bool video_waitable_swapchains;
bool video_vfilter;
bool video_smooth;
bool video_ctx_scaling;

View file

@ -197,6 +197,7 @@ typedef struct
float clearcolor[4];
unsigned swap_interval;
bool vsync;
bool waitable_swapchains;
bool wait_for_vblank;
bool resize_chain;
bool keep_aspect;

View file

@ -183,6 +183,7 @@ typedef struct
float clearcolor[4];
int frame_index;
bool vsync;
bool waitable_swapchains;
bool wait_for_vblank;
unsigned swap_interval;
#ifdef HAVE_DXGI_HDR

View file

@ -988,7 +988,8 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
d3d11->has_flip_model = true;
d3d11->has_allow_tearing = true;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
if (d3d11->waitable_swapchains)
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
#endif
@ -999,7 +1000,8 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
&desc, NULL, (IDXGISwapChain1**)&d3d11->swapChain)))
return false;
#else
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
if (d3d11->waitable_swapchains)
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
desc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
adapter->lpVtbl->GetParent(
@ -1064,7 +1066,8 @@ static bool d3d11_init_swapchain(d3d11_video_t* d3d11,
#endif /* __WINRT__ */
if ((d3d11->frameLatencyWaitableObject = DXGIGetFrameLatencyWaitableObject(d3d11->swapChain)))
if (d3d11->waitable_swapchains &&
(d3d11->frameLatencyWaitableObject = DXGIGetFrameLatencyWaitableObject(d3d11->swapChain)))
{
settings_t* settings = config_get_ptr();
UINT max_latency = settings->uints.video_max_frame_latency;
@ -1190,6 +1193,8 @@ static void *d3d11_gfx_init(const video_info_t* video,
d3d11->hdr.max_fall = 0.0f;
#endif
d3d11->waitable_swapchains = settings->bools.video_waitable_swapchains;
#ifdef __WINRT__
if (!d3d11_init_swapchain(d3d11,
d3d11->vp.full_width,
@ -1849,7 +1854,8 @@ static bool d3d11_gfx_frame(
{
UINT swapchain_flags = d3d11->has_allow_tearing
? DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING : 0;
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
if (d3d11->waitable_swapchains)
swapchain_flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
#ifdef HAVE_DXGI_HDR
d3d11->hdr.enable = video_hdr_enable;
@ -1925,7 +1931,7 @@ static bool d3d11_gfx_frame(
d3d11->hdr.max_fall);
#endif
}
else
else if (d3d11->waitable_swapchains)
{
WaitForSingleObjectEx(
d3d11->frameLatencyWaitableObject,

View file

@ -1259,7 +1259,8 @@ static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
#endif
desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_DISCARD;
desc.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_TEARING;
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
if (d3d12->chain.waitable_swapchains)
desc.Flags |= DXGI_SWAP_CHAIN_FLAG_FRAME_LATENCY_WAITABLE_OBJECT;
#ifdef __WINRT__
hr = DXGICreateSwapChainForCoreWindow(d3d12->factory, d3d12->queue.handle, corewindow, &desc, NULL, &d3d12->chain.handle);
@ -1272,7 +1273,8 @@ static bool d3d12_init_swapchain(d3d12_video_t* d3d12,
return false;
}
if ((d3d12->chain.frameLatencyWaitableObject = DXGIGetFrameLatencyWaitableObject(d3d12->chain.handle)))
if (d3d12->chain.waitable_swapchains &&
(d3d12->chain.frameLatencyWaitableObject = DXGIGetFrameLatencyWaitableObject(d3d12->chain.handle)))
{
settings_t* settings = config_get_ptr();
UINT max_latency = settings->uints.video_max_frame_latency;
@ -1778,6 +1780,8 @@ static void *d3d12_gfx_init(const video_info_t* video,
d3d12->hdr.max_fall = 0.0f;
#endif
d3d12->chain.waitable_swapchains = settings->bools.video_waitable_swapchains;
d3d_input_driver(settings->arrays.input_driver, settings->arrays.input_joypad_driver, input, input_data);
d3d12_init_base(d3d12);
@ -2163,7 +2167,7 @@ static bool d3d12_gfx_frame(
d3d12->hdr.max_fall);
#endif
}
else
else if (d3d12->chain.waitable_swapchains)
{
WaitForSingleObjectEx(
d3d12->chain.frameLatencyWaitableObject,

View file

@ -10907,6 +10907,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES,
"Tells the video driver to explicitly use a specified buffering mode."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_WAITABLE_SWAPCHAINS,
"Waitable Swapchains"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_VIDEO_WAITABLE_SWAPCHAINS,
"Hard-synchronize the CPU and GPU. Reduces latency at the cost of performance."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_VIDEO_MAX_FRAME_LATENCY,
"Max Frame Latency"

View file

@ -354,6 +354,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_timezone, MENU_
#endif
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_user_language, MENU_ENUM_SUBLABEL_USER_LANGUAGE)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_max_swapchain_images, MENU_ENUM_SUBLABEL_VIDEO_MAX_SWAPCHAIN_IMAGES)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_waitable_swapchains, MENU_ENUM_SUBLABEL_VIDEO_WAITABLE_SWAPCHAINS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_max_frame_latency, MENU_ENUM_SUBLABEL_VIDEO_MAX_FRAME_LATENCY)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_online_updater, MENU_ENUM_SUBLABEL_ONLINE_UPDATER)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_fps_show, MENU_ENUM_SUBLABEL_FPS_SHOW)
@ -4184,6 +4185,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_max_swapchain_images);
break;
case MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_waitable_swapchains);
break;
case MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_max_frame_latency);
break;

View file

@ -8568,6 +8568,7 @@ unsigned menu_displaylist_build_list(
{
bool video_vsync = settings->bools.video_vsync;
bool video_hard_sync = settings->bools.video_hard_sync;
bool video_wait_swap = settings->bools.video_waitable_swapchains;
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_VSYNC,
@ -8622,9 +8623,14 @@ unsigned menu_displaylist_build_list(
if (video_driver_test_all_flags(GFX_CTX_FLAGS_CUSTOMIZABLE_FRAME_LATENCY))
{
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY,
PARSE_ONLY_UINT, false) == 0)
MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS,
PARSE_ONLY_BOOL, false) == 0)
count++;
if (video_wait_swap)
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY,
PARSE_ONLY_UINT, false) == 0)
count++;
}
if (MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
@ -9039,6 +9045,7 @@ unsigned menu_displaylist_build_list(
case DISPLAYLIST_LATENCY_SETTINGS_LIST:
{
bool video_hard_sync = settings->bools.video_hard_sync;
bool video_wait_swap = settings->bools.video_waitable_swapchains;
#ifdef HAVE_RUNAHEAD
bool runahead_supported = true;
bool runahead_enabled = settings->bools.run_ahead_enabled;
@ -9068,9 +9075,16 @@ unsigned menu_displaylist_build_list(
if (video_driver_test_all_flags(GFX_CTX_FLAGS_CUSTOMIZABLE_FRAME_LATENCY))
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY,
PARSE_ONLY_UINT, false);
MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS,
PARSE_ONLY_BOOL, false);
count++;
if (video_wait_swap)
{
MENU_DISPLAYLIST_PARSE_SETTINGS_ENUM(list,
MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY,
PARSE_ONLY_UINT, false);
count++;
}
}
if (video_driver_test_all_flags(GFX_CTX_FLAGS_HARD_SYNC))

View file

@ -12533,6 +12533,26 @@ static bool setting_append_list(
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);
CONFIG_BOOL(
list, list_info,
&settings->bools.video_waitable_swapchains,
MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS,
MENU_ENUM_LABEL_VALUE_VIDEO_WAITABLE_SWAPCHAINS,
DEFAULT_WAITABLE_SWAPCHAINS,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
(*list)[list_info->index - 1].action_ok = setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_left = setting_bool_action_left_with_refresh;
(*list)[list_info->index - 1].action_right = setting_bool_action_right_with_refresh;
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);
CONFIG_UINT(
list, list_info,
&settings->uints.video_max_frame_latency,
@ -12546,7 +12566,7 @@ static bool setting_append_list(
general_read_handler);
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
(*list)[list_info->index - 1].offset_by = 0;
menu_settings_list_current_add_range(list, list_info, (*list)[list_info->index - 1].offset_by, 3, 1, true, true);
menu_settings_list_current_add_range(list, list_info, (*list)[list_info->index - 1].offset_by, MAXIMUM_MAX_FRAME_LATENCY, 1, true, true);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_CMD_APPLY_AUTO);
MENU_SETTINGS_LIST_CURRENT_ADD_CMD(list, list_info, CMD_EVENT_REINIT);

View file

@ -1097,6 +1097,7 @@ enum msg_hash_enums
MENU_LABEL(VIDEO_FILTER_FLICKER),
MENU_LABEL(VIDEO_SOFT_FILTER),
MENU_LABEL(VIDEO_MAX_SWAPCHAIN_IMAGES),
MENU_LABEL(VIDEO_WAITABLE_SWAPCHAINS),
MENU_LABEL(VIDEO_MAX_FRAME_LATENCY),
MENU_LABEL(VIDEO_GPU_SCREENSHOT),
MENU_LABEL(VIDEO_BLACK_FRAME_INSERTION),

View file

@ -354,6 +354,7 @@ QWidget *LatencyPage::widget()
}
layout->add(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES);
layout->add(MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS);
layout->add(MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY);
layout->add(MENU_ENUM_LABEL_VIDEO_FRAME_DELAY);
@ -1341,6 +1342,7 @@ QWidget *VideoPage::widget()
}
syncGroup->add(MENU_ENUM_LABEL_VIDEO_MAX_SWAPCHAIN_IMAGES);
syncGroup->add(MENU_ENUM_LABEL_VIDEO_WAITABLE_SWAPCHAINS);
syncGroup->add(MENU_ENUM_LABEL_VIDEO_MAX_FRAME_LATENCY);
syncGroup->add(MENU_ENUM_LABEL_VRR_RUNLOOP_ENABLE);