Merge pull request #93737 from aitorciki/disable-windowed-gsync

[Windows] Disable G-SYNC in windowed mode
This commit is contained in:
Rémi Verschelde 2024-07-19 11:10:31 +02:00
commit 18da250ffb
No known key found for this signature in database
GPG Key ID: C3336907360768E1
2 changed files with 29 additions and 16 deletions

View File

@ -76,6 +76,8 @@ static String format_error_message(DWORD id) {
const int OGL_THREAD_CONTROL_ID = 0x20C1221E;
const int OGL_THREAD_CONTROL_DISABLE = 0x00000002;
const int OGL_THREAD_CONTROL_ENABLE = 0x00000001;
const int VRR_MODE_ID = 0x1194F158;
const int VRR_MODE_FULLSCREEN_ONLY = 0x1;
typedef int(__cdecl *NvAPI_Initialize_t)();
typedef int(__cdecl *NvAPI_Unload_t)();
@ -104,10 +106,12 @@ static bool nvapi_err_check(const char *msg, int status) {
return true;
}
// On windows we have to disable threaded optimization when using NVIDIA graphics cards
// to avoid stuttering, see https://stackoverflow.com/questions/36959508/nvidia-graphics-driver-causing-noticeable-frame-stuttering/37632948
// also see https://github.com/Ryujinx/Ryujinx/blob/master/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs
void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() {
// On windows we have to customize the NVIDIA application profile:
// * disable threaded optimization when using NVIDIA cards to avoid stuttering, see
// https://stackoverflow.com/questions/36959508/nvidia-graphics-driver-causing-noticeable-frame-stuttering/37632948
// https://github.com/Ryujinx/Ryujinx/blob/master/src/Ryujinx.Common/GraphicsDriver/NVThreadedOptimization.cs
// * disable G-SYNC in windowed mode, as it results in unstable editor refresh rates
void GLManagerNative_Windows::_nvapi_setup_profile() {
HMODULE nvapi = nullptr;
#ifdef _WIN64
nvapi = LoadLibraryA("nvapi64.dll");
@ -239,21 +243,29 @@ void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() {
}
}
NVDRS_SETTING setting;
setting.version = NVDRS_SETTING_VER;
setting.settingId = OGL_THREAD_CONTROL_ID;
setting.settingType = NVDRS_DWORD_TYPE;
setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION;
setting.isCurrentPredefined = 0;
setting.isPredefinedValid = 0;
NVDRS_SETTING ogl_thread_control_setting = { 0 };
ogl_thread_control_setting.version = NVDRS_SETTING_VER;
ogl_thread_control_setting.settingId = OGL_THREAD_CONTROL_ID;
ogl_thread_control_setting.settingType = NVDRS_DWORD_TYPE;
int thread_control_val = OGL_THREAD_CONTROL_DISABLE;
if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization")) {
thread_control_val = OGL_THREAD_CONTROL_ENABLE;
}
setting.u32CurrentValue = thread_control_val;
setting.u32PredefinedValue = thread_control_val;
ogl_thread_control_setting.u32CurrentValue = thread_control_val;
if (!nvapi_err_check("NVAPI: Error calling NvAPI_DRS_SetSetting", NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting))) {
if (!nvapi_err_check("NVAPI: Error calling NvAPI_DRS_SetSetting", NvAPI_DRS_SetSetting(session_handle, profile_handle, &ogl_thread_control_setting))) {
NvAPI_DRS_DestroySession(session_handle);
NvAPI_Unload();
return;
}
NVDRS_SETTING vrr_mode_setting = { 0 };
vrr_mode_setting.version = NVDRS_SETTING_VER;
vrr_mode_setting.settingId = VRR_MODE_ID;
vrr_mode_setting.settingType = NVDRS_DWORD_TYPE;
vrr_mode_setting.u32CurrentValue = VRR_MODE_FULLSCREEN_ONLY;
if (!nvapi_err_check("NVAPI: Error calling NvAPI_DRS_SetSetting", NvAPI_DRS_SetSetting(session_handle, profile_handle, &vrr_mode_setting))) {
NvAPI_DRS_DestroySession(session_handle);
NvAPI_Unload();
return;
@ -270,6 +282,7 @@ void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() {
} else {
print_verbose("NVAPI: Enabled OpenGL threaded optimization successfully");
}
print_verbose("NVAPI: Disabled G-SYNC for windowed mode successfully");
NvAPI_DRS_DestroySession(session_handle);
}
@ -495,7 +508,7 @@ void GLManagerNative_Windows::swap_buffers() {
}
Error GLManagerNative_Windows::initialize() {
_nvapi_disable_threaded_optimization();
_nvapi_setup_profile();
return OK;
}

View File

@ -78,7 +78,7 @@ private:
int glx_minor, glx_major;
private:
void _nvapi_disable_threaded_optimization();
void _nvapi_setup_profile();
int _find_or_create_display(GLWindow &win);
Error _create_context(GLWindow &win, GLDisplay &gl_display);