diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index d35d30efd8b..758e98ad857 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2795,6 +2795,10 @@ If [code]true[/code], the forward renderer will fall back to Direct3D 12 if Vulkan is not supported. [b]Note:[/b] This setting is implemented only on Windows. + + If [code]true[/code], the forward renderer will fall back to OpenGL 3 if both Direct3D 12, Metal and Vulkan are not supported. + [b]Note:[/b] This setting is implemented only on Windows, Android, macOS, iOS, and Linux/X11. + If [code]true[/code], the forward renderer will fall back to Vulkan if Direct3D 12 is not supported. [b]Note:[/b] This setting is implemented only on Windows. diff --git a/main/main.cpp b/main/main.cpp index f1ee4bf2a6b..fa50a3039f4 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1977,6 +1977,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true); GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_d3d12", true); + GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_opengl3", true); } { diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index b88d887af52..c1053215c69 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -607,11 +607,19 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_UNAVAILABLE; - return; + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support Vulkan, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else { + ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); + r_error = ERR_UNAVAILABLE; + return; + } } union { diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index 5a027e01964..e51d43bd899 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -107,11 +107,19 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode #endif if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_UNAVAILABLE; - return; + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else { + ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); + r_error = ERR_UNAVAILABLE; + return; + } } if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) { diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index a12c9352736..7949f80f248 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6160,20 +6160,28 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_CANT_CREATE; + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your video card drivers seem not to support the required Vulkan version, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else { + r_error = ERR_CANT_CREATE; - if (p_rendering_driver == "vulkan") { - OS::get_singleton()->alert( - vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" - "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" - "You can enable the OpenGL 3 driver by starting the engine from the\n" - "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" - "If you recently updated your video card drivers, try rebooting.", - executable_name), - "Unable to initialize Vulkan video driver"); + if (p_rendering_driver == "vulkan") { + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required Vulkan version.\n\n" + "If possible, consider updating your video card drivers or using the OpenGL 3 driver.\n\n" + "You can enable the OpenGL 3 driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver opengl3\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize Vulkan video driver"); + } + + ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver)); } - - ERR_FAIL_MSG(vformat("Could not initialize %s", rendering_driver)); } driver_found = true; } diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 52dc51bc960..f6c1d11028d 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3649,8 +3649,16 @@ DisplayServerMacOS::DisplayServerMacOS(const String &p_rendering_driver, WindowM if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; - r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG("Could not initialize " + rendering_driver); + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (fallback_to_opengl3 && rendering_driver != "opengl3") { + WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + } else { + r_error = ERR_CANT_CREATE; + ERR_FAIL_MSG("Could not initialize " + rendering_driver); + } } } #endif diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 50ebe7077fd..42cd85b69ed 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6177,6 +6177,17 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } #endif + bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); + if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") { + memdelete(rendering_context); + rendering_context = nullptr; + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); + WARN_PRINT("Your video card drivers seem not to support Direct3D 12 or Vulkan, switching to OpenGL 3."); + rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_method("gl_compatibility"); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + failed = false; + } if (failed) { memdelete(rendering_context); rendering_context = nullptr;