|
@@ -76,6 +76,8 @@ static String format_error_message(DWORD id) {
|
|
const int OGL_THREAD_CONTROL_ID = 0x20C1221E;
|
|
const int OGL_THREAD_CONTROL_ID = 0x20C1221E;
|
|
const int OGL_THREAD_CONTROL_DISABLE = 0x00000002;
|
|
const int OGL_THREAD_CONTROL_DISABLE = 0x00000002;
|
|
const int OGL_THREAD_CONTROL_ENABLE = 0x00000001;
|
|
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_Initialize_t)();
|
|
typedef int(__cdecl *NvAPI_Unload_t)();
|
|
typedef int(__cdecl *NvAPI_Unload_t)();
|
|
@@ -104,10 +106,12 @@ static bool nvapi_err_check(const char *msg, int status) {
|
|
return true;
|
|
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;
|
|
HMODULE nvapi = nullptr;
|
|
#ifdef _WIN64
|
|
#ifdef _WIN64
|
|
nvapi = LoadLibraryA("nvapi64.dll");
|
|
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;
|
|
int thread_control_val = OGL_THREAD_CONTROL_DISABLE;
|
|
if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization")) {
|
|
if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization")) {
|
|
thread_control_val = OGL_THREAD_CONTROL_ENABLE;
|
|
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_DRS_DestroySession(session_handle);
|
|
NvAPI_Unload();
|
|
NvAPI_Unload();
|
|
return;
|
|
return;
|
|
@@ -270,6 +282,7 @@ void GLManagerNative_Windows::_nvapi_disable_threaded_optimization() {
|
|
} else {
|
|
} else {
|
|
print_verbose("NVAPI: Enabled OpenGL threaded optimization successfully");
|
|
print_verbose("NVAPI: Enabled OpenGL threaded optimization successfully");
|
|
}
|
|
}
|
|
|
|
+ print_verbose("NVAPI: Disabled G-SYNC for windowed mode successfully");
|
|
|
|
|
|
NvAPI_DRS_DestroySession(session_handle);
|
|
NvAPI_DRS_DestroySession(session_handle);
|
|
}
|
|
}
|
|
@@ -495,7 +508,7 @@ void GLManagerNative_Windows::swap_buffers() {
|
|
}
|
|
}
|
|
|
|
|
|
Error GLManagerNative_Windows::initialize() {
|
|
Error GLManagerNative_Windows::initialize() {
|
|
- _nvapi_disable_threaded_optimization();
|
|
|
|
|
|
+ _nvapi_setup_profile();
|
|
return OK;
|
|
return OK;
|
|
}
|
|
}
|
|
|
|
|