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

[Windows] Disable G-SYNC in windowed mode #93737

Merged
merged 1 commit into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
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
43 changes: 28 additions & 15 deletions platform/windows/gl_manager_windows_native.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)();
Expand Down Expand Up @@ -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");
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -495,7 +508,7 @@ void GLManagerNative_Windows::swap_buffers() {
}

Error GLManagerNative_Windows::initialize() {
_nvapi_disable_threaded_optimization();
_nvapi_setup_profile();
return OK;
}

Expand Down
2 changes: 1 addition & 1 deletion platform/windows/gl_manager_windows_native.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ class GLManagerNative_Windows {
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);

Expand Down
Loading