Skip to content

Commit 7c72557

Browse files
committed
Disable GPU threaded optimizations option (GL debug)
We can disable indirectly by enabling verbose GL debug output.
1 parent 34f005d commit 7c72557

File tree

6 files changed

+69
-2
lines changed

6 files changed

+69
-2
lines changed

core/os/os.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,10 @@ class OS {
341341
virtual Vector<String> get_granted_permissions() const { return Vector<String>(); }
342342
virtual void revoke_granted_permissions() {}
343343

344+
// Allow overrides "disable" and can be specified via the command line.
345+
virtual bool _is_gdriver_threaded_optimization_allowed() const { return false; }
346+
virtual void _set_gdriver_threaded_optimization_allowed(bool p_allow) {}
347+
344348
// For recording / measuring benchmark data. Only enabled with tools
345349
void set_use_benchmark(bool p_use_benchmark);
346350
bool is_use_benchmark_set();

doc/classes/ProjectSettings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2883,6 +2883,11 @@
28832883
<member name="rendering/gl_compatibility/nvidia_disable_threaded_optimization" type="bool" setter="" getter="" default="true">
28842884
If [code]true[/code], disables the threaded optimization feature from the NVIDIA drivers, which are known to cause stuttering in most OpenGL applications.
28852885
[b]Note:[/b] This setting only works on Windows, as threaded optimization is disabled by default on other platforms.
2886+
[b]Note:[/b] If [member rendering/gl_compatibility/tune_nvidia_driver] is set to [code]true[/code] the feature will be disabled directly in the driver; if set to [code]false[/code], Godot will attempt to disable the feature indirectly by enabling minimal OpenGL logging.
2887+
</member>
2888+
<member name="rendering/gl_compatibility/tune_nvidia_driver" type="bool" setter="" getter="" default="true">
2889+
If [code]true[/code], the NVIDIA drivers are tuned for G-Sync and to control threaded optimization (see [member rendering/gl_compatibility/nvidia_disable_threaded_optimization]).
2890+
[b]Note:[/b] This setting only works on Windows.
28862891
</member>
28872892
<member name="rendering/global_illumination/gi/use_half_resolution" type="bool" setter="" getter="" default="false">
28882893
If [code]true[/code], renders [VoxelGI] and SDFGI ([member Environment.sdfgi_enabled]) buffers at halved resolution (e.g. 960×540 when the viewport size is 1920×1080). This improves performance significantly when VoxelGI or SDFGI is enabled, at the cost of artifacts that may be visible on polygon edges. The loss in quality becomes less noticeable as the viewport resolution increases. [LightmapGI] rendering is not affected by this setting.

drivers/gles3/rasterizer_gles3.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ void RasterizerGLES3::clear_depth(float p_depth) {
139139
}
140140

141141
#ifdef CAN_DEBUG
142+
// We offer the option to disable GPU threaded optimizations indirectly by forcing debug output.
143+
// We aren't actually interested in the strings in this case so we try and make the call as cheap as possible.
144+
static void GLAPIENTRY _gl_debug_print_dummy(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
145+
}
146+
142147
static void GLAPIENTRY _gl_debug_print(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const GLvoid *userParam) {
143148
// These are ultimately annoying, so removing for now.
144149
if (type == _EXT_DEBUG_TYPE_OTHER_ARB || type == _EXT_DEBUG_TYPE_PERFORMANCE_ARB || type == _EXT_DEBUG_TYPE_MARKER_ARB) {
@@ -240,6 +245,26 @@ void *_egl_load_function_wrapper(const char *p_name) {
240245
RasterizerGLES3::RasterizerGLES3() {
241246
singleton = this;
242247

248+
// Use dummy OpenGL logging to indirectly disable threaded optimization if desired.
249+
bool disable_threaded_optimization = false;
250+
251+
if (OS::get_singleton()->get_name() == "Windows") {
252+
bool disable_requested = GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization");
253+
254+
// Don't disable when we are already using the Nvidia SDK technique.
255+
bool tune_driver = GLOBAL_GET("rendering/gl_compatibility/tune_nvidia_driver");
256+
257+
disable_threaded_optimization = disable_requested && !tune_driver && !OS::get_singleton()->_is_gdriver_threaded_optimization_allowed();
258+
if (disable_threaded_optimization) {
259+
String video_adapter = RenderingServer::get_singleton()->get_video_adapter_name().to_lower();
260+
261+
// Only disable for nvidia currently.
262+
if (video_adapter.find("nvidia") == -1) {
263+
disable_threaded_optimization = false;
264+
}
265+
}
266+
}
267+
243268
#ifdef GLAD_ENABLED
244269
bool glad_loaded = false;
245270

@@ -289,6 +314,14 @@ RasterizerGLES3::RasterizerGLES3() {
289314
} else {
290315
print_line("OpenGL debugging not supported!");
291316
}
317+
} else if (disable_threaded_optimization) {
318+
if (GLAD_GL_ARB_debug_output) {
319+
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
320+
glDebugMessageCallbackARB((GLDEBUGPROCARB)_gl_debug_print_dummy, nullptr);
321+
glEnable(_EXT_DEBUG_OUTPUT);
322+
} else {
323+
print_line("Disabling GPU threaded optimization via OpenGL debugging not supported by this driver.");
324+
}
292325
}
293326
}
294327
#endif // GLAD_ENABLED
@@ -304,6 +337,8 @@ RasterizerGLES3::RasterizerGLES3() {
304337
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PORTABILITY_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
305338
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_PERFORMANCE_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
306339
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_OTHER_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
340+
} else if (disable_threaded_optimization && GLAD_GL_ARB_debug_output) {
341+
glDebugMessageControlARB(_EXT_DEBUG_SOURCE_API_ARB, _EXT_DEBUG_TYPE_ERROR_ARB, _EXT_DEBUG_SEVERITY_HIGH_ARB, 0, nullptr, GL_TRUE);
307342
}
308343
}
309344
#endif // GL_API_ENABLED
@@ -321,6 +356,18 @@ RasterizerGLES3::RasterizerGLES3() {
321356
callback((DEBUGPROCARB)_gl_debug_print, nullptr);
322357
glEnable(_EXT_DEBUG_OUTPUT);
323358
}
359+
} else if (disable_threaded_optimization) {
360+
DebugMessageCallbackARB callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallback");
361+
if (!callback) {
362+
callback = (DebugMessageCallbackARB)eglGetProcAddress("glDebugMessageCallbackKHR");
363+
}
364+
365+
if (callback) {
366+
print_line("godot: ENABLING GL DEBUG dummy output");
367+
glEnable(_EXT_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
368+
callback((DEBUGPROCARB)_gl_debug_print_dummy, nullptr);
369+
glEnable(_EXT_DEBUG_OUTPUT);
370+
}
324371
}
325372
}
326373
#endif // GLES_API_ENABLED

main/main.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ void Main::print_help(const char *p_binary) {
656656
print_help_option("--disable-crash-handler", "Disable crash handler when supported by the platform code.\n");
657657
print_help_option("--fixed-fps <fps>", "Force a fixed number of frames per second. This setting disables real-time synchronization.\n");
658658
print_help_option("--delta-smoothing <enable>", "Enable or disable frame delta smoothing [\"enable\", \"disable\"].\n");
659+
print_help_option("--allow-gpu-threaded-optimization", "Override the \"nvidia_disable_threaded_optimizations\" project setting.\n");
659660
print_help_option("--print-fps", "Print the frames per second to the stdout.\n");
660661
#ifdef TOOLS_ENABLED
661662
print_help_option("--editor-pseudolocalization", "Enable pseudolocalization for the editor and the project manager.\n", CLI_OPTION_AVAILABILITY_EDITOR);
@@ -1772,6 +1773,8 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
17721773
OS::get_singleton()->print("Missing editor PID argument, aborting.\n");
17731774
goto error;
17741775
}
1776+
} else if (arg == "--allow-gpu-threaded-optimization") {
1777+
OS::get_singleton()->_set_gdriver_threaded_optimization_allowed(true);
17751778
} else if (arg == "--disable-render-loop") {
17761779
disable_render_loop = true;
17771780
} else if (arg == "--fixed-fps") {
@@ -2209,6 +2212,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
22092212
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, "opengl3,opengl3_angle"), "opengl3");
22102213

22112214
GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true);
2215+
GLOBAL_DEF_RST("rendering/gl_compatibility/tune_nvidia_driver", true);
22122216
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true);
22132217
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_native", true);
22142218
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_gles", true);

platform/windows/gl_manager_windows_native.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ void GLManagerNative_Windows::_nvapi_setup_profile() {
243243
ogl_thread_control_setting.settingId = OGL_THREAD_CONTROL_ID;
244244
ogl_thread_control_setting.settingType = NVDRS_DWORD_TYPE;
245245
int thread_control_val = OGL_THREAD_CONTROL_DISABLE;
246-
if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization")) {
246+
if (!GLOBAL_GET("rendering/gl_compatibility/nvidia_disable_threaded_optimization") || OS::get_singleton()->_is_gdriver_threaded_optimization_allowed()) {
247247
thread_control_val = OGL_THREAD_CONTROL_ENABLE;
248248
}
249249
ogl_thread_control_setting.u32CurrentValue = thread_control_val;
@@ -503,7 +503,9 @@ void GLManagerNative_Windows::swap_buffers() {
503503
}
504504

505505
Error GLManagerNative_Windows::initialize() {
506-
_nvapi_setup_profile();
506+
if (GLOBAL_GET("rendering/gl_compatibility/tune_nvidia_driver")) {
507+
_nvapi_setup_profile();
508+
}
507509
return OK;
508510
}
509511

platform/windows/os_windows.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,8 @@ class OS_Windows : public OS {
129129

130130
HashMap<void *, String> temp_libraries;
131131

132+
bool _allow_gdriver_threaded_optimizations = false;
133+
132134
void _remove_temp_library(void *p_library_handle);
133135
String _get_default_fontname(const String &p_font_name) const;
134136
DWRITE_FONT_WEIGHT _weight_to_dw(int p_weight) const;
@@ -255,6 +257,9 @@ class OS_Windows : public OS {
255257

256258
virtual String get_system_ca_certificates() override;
257259

260+
virtual bool _is_gdriver_threaded_optimization_allowed() const override { return _allow_gdriver_threaded_optimizations; }
261+
virtual void _set_gdriver_threaded_optimization_allowed(bool p_allow) override { _allow_gdriver_threaded_optimizations = p_allow; }
262+
258263
void set_main_window(HWND p_main_window) { main_window = p_main_window; }
259264

260265
#ifdef TOOLS_ENABLED

0 commit comments

Comments
 (0)