Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(nvprefs): add V-Sync and frame limiter options #3317

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -1864,6 +1864,58 @@ editing the `conf` file in a text editor. Use the examples as reference.
</tr>
</table>

### nvenc_force_disable_vsync

<table>
<tr>
<td>Description</td>
<td colspan="2">
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.}
</td>
</tr>
<tr>
<td>Default</td>
<td colspan="2">@code{}
enabled
@endcode</td>
</tr>
<tr>
<td>Example</td>
<td colspan="2">@code{}
nvenc_force_disable_vsync = enabled
@endcode</td>
</tr>
</table>

### nvenc_enable_frame_limiter

<table>
<tr>
<td>Description</td>
<td colspan="2">
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.}
</td>
</tr>
<tr>
<td>Default</td>
<td colspan="2">@code{}
enabled
@endcode</td>
</tr>
<tr>
<td>Example</td>
<td colspan="2">@code{}
nvenc_enable_frame_limiter = enabled
@endcode</td>
</tr>
</table>

## Intel QuickSync Encoder

### qsv_preset
Expand Down
4 changes: 4 additions & 0 deletions src/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

{
Expand Down Expand Up @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
54 changes: 49 additions & 5 deletions src/platform/windows/nvprefs/driver_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you can get this from #2894 after it's merged.


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);
Expand Down
2 changes: 2 additions & 0 deletions src/platform/windows/nvprefs/nvprefs_common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions src/platform/windows/nvprefs/nvprefs_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src_assets/common/assets/web/config.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,8 @@ <h1 class="my-4">{{ $t('config.configuration') }}</h1>
"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",
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,26 @@ const config = ref(props.config)
</select>
<div class="form-text">{{ $t('config.nvenc_h264_cavlc_desc') }}</div>
</div>

<!-- Force disable V-Sync (NVAPI) -->
<div class="mb-3" v-if="platform === 'windows'">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This one is fine, but I'm not sure why the one above is missing the conditional for the windows platform... or if any of them are even needed as the entire nvenc encoder is Windows only.

<label for="nvenc_force_disable_vsync" class="form-label">{{ $t('config.nvenc_force_disable_vsync') }}</label>
<select id="nvenc_force_disable_vsync" class="form-select" v-model="config.nvenc_force_disable_vsync">
<option value="disabled">{{ $t('_common.disabled') }}</option>
<option value="enabled">{{ $t('_common.enabled_def') }}</option>
</select>
<div class="form-text">{{ $t('config.nvenc_force_disable_vsync') }}</div>
</div>

<!-- Enable frame limiter (NVAPI) -->
<div class="mb-3" v-if="platform === 'windows'">
<label for="nvenc_enable_frame_limiter" class="form-label">{{ $t('config.nvenc_enable_frame_limiter') }}</label>
<select id="nvenc_enable_frame_limiter" class="form-select" v-model="config.nvenc_enable_frame_limiter">
<option value="disabled">{{ $t('_common.disabled') }}</option>
<option value="enabled">{{ $t('_common.enabled_def') }}</option>
</select>
<div class="form-text">{{ $t('config.nvenc_enable_frame_limiter') }}</div>
</div>
</div>
</div>
</div>
Expand Down
4 changes: 4 additions & 0 deletions src_assets/common/assets/web/public/assets/locale/en_US.json
Unarelith marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down