From 6280ae3988e05327fa8434e3d8a1273cb7509cae Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Sun, 20 Oct 2024 14:57:59 +0200 Subject: [PATCH 1/2] Options to force disable V-Sync / enable frame limiter using NVAPI. --- docs/configuration.md | 52 ++++++++++++++++++ src/config.cpp | 4 ++ src/config.h | 2 + .../windows/nvprefs/driver_settings.cpp | 54 +++++++++++++++++-- .../windows/nvprefs/nvprefs_common.cpp | 2 + src/platform/windows/nvprefs/nvprefs_common.h | 2 + src_assets/common/assets/web/config.html | 2 + .../tabs/encoders/NvidiaNvencEncoder.vue | 20 +++++++ .../web/public/assets/locale/en_US.json | 4 ++ 9 files changed, 137 insertions(+), 5 deletions(-) diff --git a/docs/configuration.md b/docs/configuration.md index f853e418e1f..52af78828c5 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -1864,6 +1864,58 @@ editing the `conf` file in a text editor. Use the examples as reference. +### nvenc_force_disable_vsync + + + + + + + + + + + + + + +
Description + Force disable V-Sync using NVAPI. + In-game V-Sync should also be disabled to prevent input lag. + @note{This option only applies when using NVENC [encoder](#encoder).} + @note{Applies to Windows only.} +
Default@code{} + enabled + @endcode
Example@code{} + nvenc_force_disable_vsync = enabled + @endcode
+ +### nvenc_enable_frame_limiter + + + + + + + + + + + + + + +
Description + Limit frames based on the host refresh rate using NVAPI. + If V-Sync is disabled, this option should be turned on to prevent rendering too much frames. + @note{This option only applies when using NVENC [encoder](#encoder).} + @note{Applies to Windows only.} +
Default@code{} + enabled + @endcode
Example@code{} + nvenc_enable_frame_limiter = enabled + @endcode
+ ## Intel QuickSync Encoder ### qsv_preset diff --git a/src/config.cpp b/src/config.cpp index b42eb097a5d..4eea9febaf2 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -346,6 +346,8 @@ namespace config { true, // nv_realtime_hags true, // nv_opengl_vulkan_on_dxgi true, // nv_sunshine_high_power_mode + true, // nv_force_disable_vsync + true, // nv_enable_frame_limiter {}, // nv_legacy { @@ -966,6 +968,8 @@ namespace config { bool_f(vars, "nvenc_realtime_hags", video.nv_realtime_hags); bool_f(vars, "nvenc_opengl_vulkan_on_dxgi", video.nv_opengl_vulkan_on_dxgi); bool_f(vars, "nvenc_latency_over_power", video.nv_sunshine_high_power_mode); + bool_f(vars, "nvenc_force_disable_vsync", video.nv_force_disable_vsync); + bool_f(vars, "nvenc_enable_frame_limiter", video.nv_enable_frame_limiter); #ifndef __APPLE__ video.nv_legacy.preset = video.nv.quality_preset + 11; diff --git a/src/config.h b/src/config.h index c987fc543bf..3be9afa10f8 100644 --- a/src/config.h +++ b/src/config.h @@ -33,6 +33,8 @@ namespace config { bool nv_realtime_hags; bool nv_opengl_vulkan_on_dxgi; bool nv_sunshine_high_power_mode; + bool nv_force_disable_vsync; + bool nv_enable_frame_limiter; struct { int preset; diff --git a/src/platform/windows/nvprefs/driver_settings.cpp b/src/platform/windows/nvprefs/driver_settings.cpp index 2cea9fa4c58..58d2e029873 100644 --- a/src/platform/windows/nvprefs/driver_settings.cpp +++ b/src/platform/windows/nvprefs/driver_settings.cpp @@ -162,11 +162,6 @@ namespace nvprefs { undo_data.reset(); NvAPI_Status status; - if (!get_nvprefs_options().opengl_vulkan_on_dxgi) { - // User requested to leave OpenGL/Vulkan DXGI swapchain setting alone - return true; - } - NvDRSProfileHandle profile_handle = 0; status = NvAPI_DRS_GetBaseProfile(session_handle, &profile_handle); if (status != NVAPI_OK) { @@ -175,6 +170,55 @@ namespace nvprefs { return false; } + if (get_nvprefs_options().force_disable_vsync) + { + NVDRS_SETTING setting = {}; + setting.version = NVDRS_SETTING_VER; + status = NvAPI_DRS_GetSetting(session_handle, profile_handle, VSYNCMODE_ID, &setting); + if (status != NVAPI_OK) { + nvapi_error_message(status); + error_message("NvAPI_DRS_GetSetting() VSYNCMODE failed"); + return false; + } + + // TODO: save current setting and restore it later + setting.u32CurrentValue = VSYNCMODE_FORCEOFF; + + status = NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting); + if (status != NVAPI_OK) { + nvapi_error_message(status); + error_message("NvAPI_DRS_SetSetting() VSYNCMODE failed"); + return false; + } + } + + if (get_nvprefs_options().enable_frame_limiter) + { + NVDRS_SETTING setting = {}; + setting.version = NVDRS_SETTING_VER; + status = NvAPI_DRS_GetSetting(session_handle, profile_handle, FRL_FPS_ID, &setting); + if (status != NVAPI_OK) { + nvapi_error_message(status); + error_message("NvAPI_DRS_GetSetting() FRL_FPS_ID failed"); + return false; + } + + // TODO: save current setting and restore it later + setting.u32CurrentValue = 60; // TODO: change this according to host refresh rate + + status = NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting); + if (status != NVAPI_OK) { + nvapi_error_message(status); + error_message("NvAPI_DRS_SetSetting() FRL_FPS_ID failed"); + return false; + } + } + + if (!get_nvprefs_options().opengl_vulkan_on_dxgi) { + // User requested to leave OpenGL/Vulkan DXGI swapchain setting alone + return true; + } + NVDRS_SETTING setting = {}; setting.version = NVDRS_SETTING_VER; status = NvAPI_DRS_GetSetting(session_handle, profile_handle, OGL_CPL_PREFER_DXPRESENT_ID, &setting); diff --git a/src/platform/windows/nvprefs/nvprefs_common.cpp b/src/platform/windows/nvprefs/nvprefs_common.cpp index 902ff81ae65..a946ccf91aa 100644 --- a/src/platform/windows/nvprefs/nvprefs_common.cpp +++ b/src/platform/windows/nvprefs/nvprefs_common.cpp @@ -36,6 +36,8 @@ namespace nvprefs { nvprefs_options options; options.opengl_vulkan_on_dxgi = config::video.nv_opengl_vulkan_on_dxgi; options.sunshine_high_power_mode = config::video.nv_sunshine_high_power_mode; + options.force_disable_vsync = config::video.nv_force_disable_vsync; + options.enable_frame_limiter = config::video.nv_enable_frame_limiter; return options; } diff --git a/src/platform/windows/nvprefs/nvprefs_common.h b/src/platform/windows/nvprefs/nvprefs_common.h index aa6c00fa3b3..32d37408cde 100644 --- a/src/platform/windows/nvprefs/nvprefs_common.h +++ b/src/platform/windows/nvprefs/nvprefs_common.h @@ -52,6 +52,8 @@ namespace nvprefs { struct nvprefs_options { bool opengl_vulkan_on_dxgi = true; bool sunshine_high_power_mode = true; + bool force_disable_vsync = true; + bool enable_frame_limiter = true; }; nvprefs_options diff --git a/src_assets/common/assets/web/config.html b/src_assets/common/assets/web/config.html index 3c9cb3aa651..1306c266bf7 100644 --- a/src_assets/common/assets/web/config.html +++ b/src_assets/common/assets/web/config.html @@ -225,6 +225,8 @@

{{ $t('config.configuration') }}

"nvenc_latency_over_power": "enabled", "nvenc_opengl_vulkan_on_dxgi": "enabled", "nvenc_h264_cavlc": "disabled", + "nvenc_force_disable_vsync": "enabled", + "nvenc_enable_frame_limiter": "enabled", }, }, { diff --git a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue index aa6ad003ac2..984ec49535f 100644 --- a/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue +++ b/src_assets/common/assets/web/configs/tabs/encoders/NvidiaNvencEncoder.vue @@ -114,6 +114,26 @@ const config = ref(props.config)
{{ $t('config.nvenc_h264_cavlc_desc') }}
+ + +
+ + +
{{ $t('config.nvenc_force_disable_vsync') }}
+
+ + +
+ + +
{{ $t('config.nvenc_enable_frame_limiter') }}
+
diff --git a/src_assets/common/assets/web/public/assets/locale/en_US.json b/src_assets/common/assets/web/public/assets/locale/en_US.json index 12844fcf874..a4d78c6e6b7 100644 --- a/src_assets/common/assets/web/public/assets/locale/en_US.json +++ b/src_assets/common/assets/web/public/assets/locale/en_US.json @@ -223,6 +223,10 @@ "native_pen_touch_desc": "When enabled, Sunshine will pass through native pen/touch events from Moonlight clients. This can be useful to disable for older applications without native pen/touch support.", "notify_pre_releases": "PreRelease Notifications", "notify_pre_releases_desc": "Whether to be notified of new pre-release versions of Sunshine", + "nvenc_enable_frame_limiter": "Enable frame limiter", + "nvenc_enable_frame_limiter_desc": "Limit frames based on the host refresh rate. If V-Sync is disabled, this option should be turned on to prevent rendering too much frames.", + "nvenc_force_disable_vsync": "Force disable V-Sync", + "nvenc_force_disable_vsync_desc": "In-game V-Sync should also be disabled to prevent input lag.", "nvenc_h264_cavlc": "Prefer CAVLC over CABAC in H.264", "nvenc_h264_cavlc_desc": "Simpler form of entropy coding. CAVLC needs around 10% more bitrate for same quality. Only relevant for really old decoding devices.", "nvenc_latency_over_power": "Prefer lower encoding latency over power savings", From a57e355f6c7713686ba1af2a632abf8e62f67b09 Mon Sep 17 00:00:00 2001 From: Quentin Bazin Date: Sun, 20 Oct 2024 17:15:42 +0200 Subject: [PATCH 2/2] Moved new text to en.json. --- src_assets/common/assets/web/public/assets/locale/en.json | 4 ++++ src_assets/common/assets/web/public/assets/locale/en_US.json | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src_assets/common/assets/web/public/assets/locale/en.json b/src_assets/common/assets/web/public/assets/locale/en.json index 12844fcf874..a4d78c6e6b7 100644 --- a/src_assets/common/assets/web/public/assets/locale/en.json +++ b/src_assets/common/assets/web/public/assets/locale/en.json @@ -223,6 +223,10 @@ "native_pen_touch_desc": "When enabled, Sunshine will pass through native pen/touch events from Moonlight clients. This can be useful to disable for older applications without native pen/touch support.", "notify_pre_releases": "PreRelease Notifications", "notify_pre_releases_desc": "Whether to be notified of new pre-release versions of Sunshine", + "nvenc_enable_frame_limiter": "Enable frame limiter", + "nvenc_enable_frame_limiter_desc": "Limit frames based on the host refresh rate. If V-Sync is disabled, this option should be turned on to prevent rendering too much frames.", + "nvenc_force_disable_vsync": "Force disable V-Sync", + "nvenc_force_disable_vsync_desc": "In-game V-Sync should also be disabled to prevent input lag.", "nvenc_h264_cavlc": "Prefer CAVLC over CABAC in H.264", "nvenc_h264_cavlc_desc": "Simpler form of entropy coding. CAVLC needs around 10% more bitrate for same quality. Only relevant for really old decoding devices.", "nvenc_latency_over_power": "Prefer lower encoding latency over power savings", diff --git a/src_assets/common/assets/web/public/assets/locale/en_US.json b/src_assets/common/assets/web/public/assets/locale/en_US.json index a4d78c6e6b7..12844fcf874 100644 --- a/src_assets/common/assets/web/public/assets/locale/en_US.json +++ b/src_assets/common/assets/web/public/assets/locale/en_US.json @@ -223,10 +223,6 @@ "native_pen_touch_desc": "When enabled, Sunshine will pass through native pen/touch events from Moonlight clients. This can be useful to disable for older applications without native pen/touch support.", "notify_pre_releases": "PreRelease Notifications", "notify_pre_releases_desc": "Whether to be notified of new pre-release versions of Sunshine", - "nvenc_enable_frame_limiter": "Enable frame limiter", - "nvenc_enable_frame_limiter_desc": "Limit frames based on the host refresh rate. If V-Sync is disabled, this option should be turned on to prevent rendering too much frames.", - "nvenc_force_disable_vsync": "Force disable V-Sync", - "nvenc_force_disable_vsync_desc": "In-game V-Sync should also be disabled to prevent input lag.", "nvenc_h264_cavlc": "Prefer CAVLC over CABAC in H.264", "nvenc_h264_cavlc_desc": "Simpler form of entropy coding. CAVLC needs around 10% more bitrate for same quality. Only relevant for really old decoding devices.", "nvenc_latency_over_power": "Prefer lower encoding latency over power savings",