From f971c886fadd8490f24ee3ea3d6b50e2574bacf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Tue, 28 Jun 2022 11:21:55 +0200 Subject: [PATCH] Add safe defaults for async shader compilation --- doc/classes/ProjectSettings.xml | 30 ++++++++++++++++++++++-------- servers/visual_server.cpp | 5 ++++- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index 28f9fa29411..602d36958de 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -1516,22 +1516,32 @@ At runtime, while that count is reached, other shaders that can be asynchronously compiled will just use their fallback, without their setup being started until the count gets lower. This is a way to balance the CPU work between running the game and compiling the shaders. The goal is to have as many asynchronous compiles in flight as possible without impacting the responsiveness of the game, which beyond some point would destroy the benefits of asynchronous compilation. In other words, you may be able to afford that the FPS lowers a bit, and that will already be better than the stalling that synchronous compilation could cause. The default value is a conservative one, so you are advised to tweak it according to the hardware you are targeting. - [b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/code]. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]. - The default is a very conservative override for [code]rendering/gles3/shaders/max_concurrent_compiles[/code]. + The default is a very conservative override for [member rendering/gles3/shaders/max_simultaneous_compiles]. Depending on the specific devices you are targeting, you may want to raise it. - [b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/shaders/shader_compilation_mode[/code] is [b]not[/b] [code]Synchronous[/code]. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]. + + + The default is a very conservative override for [member rendering/gles3/shaders/max_simultaneous_compiles]. + Depending on the specific browsers you are targeting, you may want to raise it. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is [b]not[/b] [code]Synchronous[/code]. The maximum size, in megabytes, that the ubershader cache can grow up to. On startup, the least recently used entries will be deleted until the total size is within bounds. - [b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/code]. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]. - An override for [code]rendering/gles3/shaders/ubershader_cache_size_mb[/code], so a smaller maximum size can be configured for mobile platforms, where storage space is more limited. - [b]Note:[/b] This setting is only meaningful if [code]rendering/gles3/shaders/shader_compilation_mode[/code] is set to [code]Asynchronous + Cache[/code]. + An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a smaller maximum size can be configured for mobile platforms, where storage space is more limited. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]. - + + An override for [member rendering/gles3/shaders/shader_cache_size_mb], so a smaller maximum size can be configured for web platforms, where storage space is more limited. + [b]Note:[/b] Currently, shader caching is generally unavailable on web platforms. + [b]Note:[/b] This setting is only meaningful if [member rendering/gles3/shaders/shader_compilation_mode] is set to [code]Asynchronous + Cache[/code]. + + If set to [code]Asynchronous[/code] and available on the target device, asynchronous compilation of shaders is enabled (in contrast to [code]Asynchronous[/code]). That means that when a shader is first used under some new rendering situation, the game won't stall while such shader is being compiled. Instead, a fallback will be used and the real shader will be compiled in the background. Once the actual shader is compiled, it will be used the next times it's used to draw a frame. Depending on the async mode configured for a given material/shader, the fallback will be an "ubershader" (the default) or just skip rendering any item it is applied to. @@ -1540,9 +1550,13 @@ [b]Note:[/b] Asynchronous compilation is currently only supported for spatial (3D) and particle materials/shaders. CanvasItem (2D) shaders will not use asynchronous compilation even if this setting is set to [code]Asynchronous[/code] or [code]Asynchronous + Cache[/code]. - An override for [code]rendering/gles3/shaders/shader_compilation_mode[/code], so asynchronous compilation can be disabled for mobile. + An override for [member rendering/gles3/shaders/shader_compilation_mode], so asynchronous compilation can be disabled on mobile platforms. You may want to do that since mobile GPUs generally won't support ubershaders due to their complexity. + + An override for [member rendering/gles3/shaders/shader_compilation_mode], so asynchronous compilation can be disabled on web platforms. + You may want to do that since certain browsers (especially on mobile platforms) generally won't support ubershaders due to their complexity. + Max buffer size for blend shapes. Any blend shape bigger than this will not work. diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 5baf0ebaffa..ff6c9ae07db 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2735,16 +2735,19 @@ VisualServer::VisualServer() { force_shader_fallbacks = GLOBAL_GET("rendering/gles3/shaders/debug_shader_fallbacks"); } #endif - GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode", 2); + GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode", 0); ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/shader_compilation_mode", PropertyInfo(Variant::INT, "rendering/gles3/shaders/shader_compilation_mode", PROPERTY_HINT_ENUM, "Synchronous,Asynchronous,Asynchronous + Cache")); GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode.mobile", 0); + GLOBAL_DEF("rendering/gles3/shaders/shader_compilation_mode.web", 0); GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles", 2); ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/max_simultaneous_compiles", PropertyInfo(Variant::INT, "rendering/gles3/shaders/max_simultaneous_compiles", PROPERTY_HINT_RANGE, "1,8,1")); GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles.mobile", 1); + GLOBAL_DEF("rendering/gles3/shaders/max_simultaneous_compiles.web", 1); GLOBAL_DEF("rendering/gles3/shaders/log_active_async_compiles_count", false); GLOBAL_DEF("rendering/gles3/shaders/shader_cache_size_mb", 512); ProjectSettings::get_singleton()->set_custom_property_info("rendering/gles3/shaders/shader_cache_size_mb", PropertyInfo(Variant::INT, "rendering/gles3/shaders/shader_cache_size_mb", PROPERTY_HINT_RANGE, "128,4096,128")); GLOBAL_DEF("rendering/gles3/shaders/shader_cache_size_mb.mobile", 128); + GLOBAL_DEF("rendering/gles3/shaders/shader_cache_size_mb.web", 128); } VisualServer::~VisualServer() {