From 80389d750fefdb1cd630f3991ea82d5718ce742f Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Tue, 30 Jul 2024 22:19:06 +0300 Subject: [PATCH 01/15] [Windows] Improve video driver error messages. --- platform/windows/display_server_windows.cpp | 55 ++++++++++++++------- platform/windows/display_server_windows.h | 8 +++ 2 files changed, 45 insertions(+), 18 deletions(-) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index ef5644c7d884..a402691c5716 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -5779,6 +5779,8 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, return id; } +BitField DisplayServerWindows::tested_drivers = 0; + // WinTab API. bool DisplayServerWindows::wintab_available = false; WTOpenPtr DisplayServerWindows::wintab_WTOpen = nullptr; @@ -5935,6 +5937,8 @@ void DisplayServerWindows::tablet_set_current_driver(const String &p_driver) { DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { KeyMappingWindows::initialize(); + tested_drivers.clear(); + drop_events = false; key_event_pos = 0; @@ -6103,7 +6107,6 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win wc.lpszClassName = L"Engine"; if (!RegisterClassExW(&wc)) { - MessageBoxW(nullptr, L"Failed To Register The Window Class.", L"ERROR", MB_OK | MB_ICONEXCLAMATION); r_error = ERR_UNAVAILABLE; return; } @@ -6114,11 +6117,13 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { rendering_context = memnew(RenderingContextDriverVulkanWindows); + tested_drivers.set_flag(DRIVER_ID_RD_VULKAN); } #endif #if defined(D3D12_ENABLED) if (rendering_driver == "d3d12") { rendering_context = memnew(RenderingContextDriverD3D12); + tested_drivers.set_flag(DRIVER_ID_RD_D3D12); } #endif @@ -6130,6 +6135,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (failed && fallback_to_vulkan && rendering_driver != "vulkan") { memdelete(rendering_context); rendering_context = memnew(RenderingContextDriverVulkanWindows); + tested_drivers.set_flag(DRIVER_ID_RD_VULKAN); if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Direct3D 12, switching to Vulkan."); rendering_driver = "vulkan"; @@ -6142,6 +6148,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (failed && fallback_to_d3d12 && rendering_driver != "d3d12") { memdelete(rendering_context); rendering_context = memnew(RenderingContextDriverD3D12); + tested_drivers.set_flag(DRIVER_ID_RD_D3D12); if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Vulkan, switching to Direct3D 12."); rendering_driver = "d3d12"; @@ -6212,6 +6219,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } if (force_angle || (gl_info["version"].operator int() < 30003)) { + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); if (show_warning) { WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE."); } @@ -6221,6 +6229,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (rendering_driver == "opengl3") { gl_manager_native = memnew(GLManagerNative_Windows); + tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); if (gl_manager_native->initialize() != OK) { memdelete(gl_manager_native); @@ -6233,6 +6242,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } if (rendering_driver == "opengl3_angle") { gl_manager_angle = memnew(GLManagerANGLE_Windows); + tested_drivers.set_flag(DRIVER_ID_COMPAT_ANGLE_D3D11); if (gl_manager_angle->initialize() != OK) { memdelete(gl_manager_angle); @@ -6366,32 +6376,41 @@ Vector DisplayServerWindows::get_rendering_drivers_func() { DisplayServer *DisplayServerWindows::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { DisplayServer *ds = memnew(DisplayServerWindows(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error)); if (r_error != OK) { - if (p_rendering_driver == "vulkan") { - String executable_name = OS::get_singleton()->get_executable_path().get_file(); - 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 have recently updated your video card drivers, try rebooting.", - executable_name), - "Unable to initialize Vulkan video driver"); - } else if (p_rendering_driver == "d3d12") { + if (tested_drivers == 0) { + OS::get_singleton()->alert("Failed to register the window class.", "Unable to initialize DisplayServer"); + } else if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN) || tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) { + Vector drivers; + if (tested_drivers.has_flag(DRIVER_ID_RD_VULKAN)) { + drivers.push_back("Vulkan"); + } + if (tested_drivers.has_flag(DRIVER_ID_RD_D3D12)) { + drivers.push_back("Direct3D 12"); + } String executable_name = OS::get_singleton()->get_executable_path().get_file(); OS::get_singleton()->alert( - vformat("Your video card drivers seem not to support the required DirectX 12 version.\n\n" + vformat("Your video card drivers seem not to support the required %s 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 have recently updated your video card drivers, try rebooting.", + String(" or ").join(drivers), executable_name), - "Unable to initialize DirectX 12 video driver"); + "Unable to initialize video driver"); } else { + Vector drivers; + if (tested_drivers.has_flag(DRIVER_ID_COMPAT_OPENGL3)) { + drivers.push_back("OpenGL 3.3"); + } + if (tested_drivers.has_flag(DRIVER_ID_COMPAT_ANGLE_D3D11)) { + drivers.push_back("Direct3D 11"); + } OS::get_singleton()->alert( - "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" - "If possible, consider updating your video card drivers.\n\n" - "If you have recently updated your video card drivers, try rebooting.", - "Unable to initialize OpenGL video driver"); + vformat( + "Your video card drivers seem not to support the required %s version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you have recently updated your video card drivers, try rebooting.", + String(" or ").join(drivers)), + "Unable to initialize video driver"); } } return ds; diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 03132bb0dbc9..54e1c9681ddc 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -394,6 +394,14 @@ class DisplayServerWindows : public DisplayServer { String tablet_driver; Vector tablet_drivers; + enum DriverID { + DRIVER_ID_COMPAT_OPENGL3 = 1 << 0, + DRIVER_ID_COMPAT_ANGLE_D3D11 = 1 << 1, + DRIVER_ID_RD_VULKAN = 1 << 2, + DRIVER_ID_RD_D3D12 = 1 << 3, + }; + static BitField tested_drivers; + enum TimerID { TIMER_ID_MOVE_REDRAW = 1, TIMER_ID_WINDOW_ACTIVATION = 2, From c31f4572891a8f82401bdff0f558fd7c2c9c77c0 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Thu, 25 Apr 2024 10:37:38 -0700 Subject: [PATCH 02/15] Check if RD is supported in the ProjectManager and disable creating RD projects if not supported. --- editor/project_manager/project_dialog.cpp | 32 +++++++++++++++-- editor/project_manager/project_dialog.h | 2 ++ servers/display_server.cpp | 42 +++++++++++++++++++++++ servers/display_server.h | 2 ++ 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/editor/project_manager/project_dialog.cpp b/editor/project_manager/project_dialog.cpp index ce7389b3ea4f..b1791c66ab64 100644 --- a/editor/project_manager/project_dialog.cpp +++ b/editor/project_manager/project_dialog.cpp @@ -444,6 +444,8 @@ void ProjectDialog::_renderer_selected() { String renderer_type = renderer_button_group->get_pressed_button()->get_meta(SNAME("rendering_method")); + bool rd_error = false; + if (renderer_type == "forward_plus") { renderer_info->set_text( String::utf8("• ") + TTR("Supports desktop platforms only.") + @@ -451,6 +453,7 @@ void ProjectDialog::_renderer_selected() { String::utf8("\n• ") + TTR("Can scale to large complex scenes.") + String::utf8("\n• ") + TTR("Uses RenderingDevice backend.") + String::utf8("\n• ") + TTR("Slower rendering of simple scenes.")); + rd_error = !rendering_device_supported; } else if (renderer_type == "mobile") { renderer_info->set_text( String::utf8("• ") + TTR("Supports desktop + mobile platforms.") + @@ -458,16 +461,24 @@ void ProjectDialog::_renderer_selected() { String::utf8("\n• ") + TTR("Less scalable for complex scenes.") + String::utf8("\n• ") + TTR("Uses RenderingDevice backend.") + String::utf8("\n• ") + TTR("Fast rendering of simple scenes.")); + rd_error = !rendering_device_supported; } else if (renderer_type == "gl_compatibility") { renderer_info->set_text( String::utf8("• ") + TTR("Supports desktop, mobile + web platforms.") + - String::utf8("\n• ") + TTR("Least advanced 3D graphics (currently work-in-progress).") + + String::utf8("\n• ") + TTR("Least advanced 3D graphics.") + String::utf8("\n• ") + TTR("Intended for low-end/older devices.") + String::utf8("\n• ") + TTR("Uses OpenGL 3 backend (OpenGL 3.3/ES 3.0/WebGL2).") + String::utf8("\n• ") + TTR("Fastest rendering of simple scenes.")); } else { WARN_PRINT("Unknown renderer type. Please report this as a bug on GitHub."); } + + rd_not_supported->set_visible(rd_error); + get_ok_button()->set_disabled(rd_error); + if (rd_error) { + // Needs to be set here since theme colors aren't available at startup. + rd_not_supported->add_theme_color_override(SceneStringName(font_color), get_theme_color(SNAME("error_color"), EditorStringName(Editor))); + } } void ProjectDialog::_nonempty_confirmation_ok_pressed() { @@ -922,10 +933,16 @@ ProjectDialog::ProjectDialog() { default_renderer_type = EditorSettings::get_singleton()->get_setting("project_manager/default_renderer"); } + rendering_device_supported = DisplayServer::can_create_rendering_device(); + + if (!rendering_device_supported) { + default_renderer_type = "gl_compatibility"; + } + Button *rs_button = memnew(CheckBox); rs_button->set_button_group(renderer_button_group); rs_button->set_text(TTR("Forward+")); -#if defined(WEB_ENABLED) +#ifndef RD_ENABLED rs_button->set_disabled(true); #endif rs_button->set_meta(SNAME("rendering_method"), "forward_plus"); @@ -937,7 +954,7 @@ ProjectDialog::ProjectDialog() { rs_button = memnew(CheckBox); rs_button->set_button_group(renderer_button_group); rs_button->set_text(TTR("Mobile")); -#if defined(WEB_ENABLED) +#ifndef RD_ENABLED rs_button->set_disabled(true); #endif rs_button->set_meta(SNAME("rendering_method"), "mobile"); @@ -969,6 +986,15 @@ ProjectDialog::ProjectDialog() { renderer_info = memnew(Label); renderer_info->set_modulate(Color(1, 1, 1, 0.7)); rvb->add_child(renderer_info); + + rd_not_supported = memnew(Label); + rd_not_supported->set_text(TTR("Rendering Device backend not available. Please use the Compatibility renderer.")); + rd_not_supported->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER); + rd_not_supported->set_custom_minimum_size(Size2(200, 0) * EDSCALE); + rd_not_supported->set_autowrap_mode(TextServer::AUTOWRAP_WORD_SMART); + rd_not_supported->set_visible(false); + renderer_container->add_child(rd_not_supported); + _renderer_selected(); l = memnew(Label); diff --git a/editor/project_manager/project_dialog.h b/editor/project_manager/project_dialog.h index 559147e7c94b..875b19a57b19 100644 --- a/editor/project_manager/project_dialog.h +++ b/editor/project_manager/project_dialog.h @@ -79,6 +79,8 @@ class ProjectDialog : public ConfirmationDialog { Label *renderer_info = nullptr; HBoxContainer *default_files_container = nullptr; Ref renderer_button_group; + bool rendering_device_supported = false; + Label *rd_not_supported = nullptr; Label *msg = nullptr; LineEdit *project_name = nullptr; diff --git a/servers/display_server.cpp b/servers/display_server.cpp index 54510576459b..8cb3e560ac9f 100644 --- a/servers/display_server.cpp +++ b/servers/display_server.cpp @@ -34,6 +34,14 @@ #include "scene/resources/texture.h" #include "servers/display_server_headless.h" +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_context_driver_vulkan.h" +#undef CursorShape +#endif +#if defined(D3D12_ENABLED) +#include "drivers/d3d12/rendering_context_driver_d3d12.h" +#endif + DisplayServer *DisplayServer::singleton = nullptr; bool DisplayServer::hidpi_allowed = false; @@ -1211,6 +1219,40 @@ void DisplayServer::_input_set_custom_mouse_cursor_func(const Ref &p_i singleton->cursor_set_custom_image(p_image, (CursorShape)p_shape, p_hostspot); } +bool DisplayServer::can_create_rendering_device() { +#if defined(RD_ENABLED) + Error err; + RenderingContextDriver *rcd = nullptr; + +#if defined(VULKAN_ENABLED) + rcd = memnew(RenderingContextDriverVulkan); +#endif +#ifdef D3D12_ENABLED + if (rcd == nullptr) { + rcd = memnew(RenderingContextDriverD3D12); + } +#endif + + if (rcd != nullptr) { + err = rcd->initialize(); + if (err == OK) { + RenderingDevice *rd = memnew(RenderingDevice); + err = rd->initialize(rcd); + memdelete(rd); + rd = nullptr; + if (err == OK) { + return true; + } + } + + memdelete(rcd); + rcd = nullptr; + } + +#endif // RD_ENABLED + return false; +} + DisplayServer::DisplayServer() { singleton = this; Input::set_mouse_mode_func = _input_set_mouse_mode; diff --git a/servers/display_server.h b/servers/display_server.h index d0fe76faff37..04f4b0c03d25 100644 --- a/servers/display_server.h +++ b/servers/display_server.h @@ -594,6 +594,8 @@ class DisplayServer : public Object { static Vector get_create_function_rendering_drivers(int p_index); static DisplayServer *create(int p_index, const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error); + static bool can_create_rendering_device(); + DisplayServer(); ~DisplayServer(); }; From a4e34112a5f206bd333f478f1df63d0fac2ce5b8 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Sun, 25 Aug 2024 22:52:01 +0300 Subject: [PATCH 03/15] [Windows] Move __REQUIRED_RPCNDR_H_VERSION__ to the header. --- drivers/d3d12/SCsub | 1 - drivers/d3d12/rendering_device_driver_d3d12.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/d3d12/SCsub b/drivers/d3d12/SCsub index 55ba1dc579c5..f1264f040d3d 100644 --- a/drivers/d3d12/SCsub +++ b/drivers/d3d12/SCsub @@ -138,7 +138,6 @@ if env.msvc: ] else: extra_defines += [ - ("__REQUIRED_RPCNDR_H_VERSION__", 475), "HAVE_STRUCT_TIMESPEC", ] diff --git a/drivers/d3d12/rendering_device_driver_d3d12.h b/drivers/d3d12/rendering_device_driver_d3d12.h index 61b1498755f6..fb7fbdc02d79 100644 --- a/drivers/d3d12/rendering_device_driver_d3d12.h +++ b/drivers/d3d12/rendering_device_driver_d3d12.h @@ -36,6 +36,11 @@ #include "core/templates/self_list.h" #include "servers/rendering/rendering_device_driver.h" +#ifndef _MSC_VER +// Match current version used by MinGW, MSVC and Direct3D 12 headers use 500. +#define __REQUIRED_RPCNDR_H_VERSION__ 475 +#endif + #if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wnon-virtual-dtor" From f97b489a6352da6ef91d99b7ff88db8787f76102 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 22 Aug 2024 09:46:01 +0300 Subject: [PATCH 04/15] Enable fallback from ANGLE to native and improve ANGLE error messages. --- doc/classes/ProjectSettings.xml | 4 +- drivers/egl/egl_manager.cpp | 4 +- platform/macos/display_server_macos.mm | 6 ++- platform/windows/display_server_windows.cpp | 44 +++++++++++++++------ 4 files changed, 40 insertions(+), 18 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index d78fca5e16cd..f1fe9c38f691 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2526,8 +2526,8 @@ [b]Note:[/b] This setting is implemented only on Linux/X11. - If [code]true[/code], the compatibility renderer will fall back to native OpenGL if ANGLE over Metal is not supported. - [b]Note:[/b] This setting is implemented only on macOS. + If [code]true[/code], the compatibility renderer will fall back to native OpenGL if ANGLE is not supported, or ANGLE dynamic libraries aren't found. + [b]Note:[/b] This setting is implemented on macOS and Windows. An [Array] of devices which should always use the ANGLE renderer. diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 9c1d08331d25..4477ba7752cb 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -357,7 +357,7 @@ Error EGLManager::initialize(void *p_native_display) { // have to temporarily get a proper display and reload EGL once again to // initialize everything else. if (!gladLoaderLoadEGL(EGL_NO_DISPLAY)) { - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL dynamic library."); } EGLDisplay tmp_display = EGL_NO_DISPLAY; @@ -387,7 +387,7 @@ Error EGLManager::initialize(void *p_native_display) { int version = gladLoaderLoadEGL(tmp_display); if (!version) { eglTerminate(tmp_display); - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL."); + ERR_FAIL_V_MSG(ERR_UNAVAILABLE, "Can't load EGL dynamic library."); } int major = GLAD_VERSION_MAJOR(version); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 22586a777586..72f939a12d50 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3598,7 +3598,11 @@ gl_manager_angle = nullptr; bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native"); if (fallback) { - WARN_PRINT("Your video card drivers seem not to support the required Metal version, switching to native OpenGL."); +#ifdef EGL_STATIC + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL."); +#else + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dylib and libGLESv2.dylib) are missing, switching to native OpenGL."); +#endif rendering_driver = "opengl3"; } else { r_error = ERR_UNAVAILABLE; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index a402691c5716..47dd3a096eaa 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6194,10 +6194,12 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win #endif } + bool gl_supported = true; if (fallback && (rendering_driver == "opengl3")) { Dictionary gl_info = detect_wgl(); bool force_angle = false; + gl_supported = gl_info["version"].operator int() >= 30003; Vector2i device_id = _get_device_ids(gl_info["name"]); Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices"); @@ -6221,12 +6223,37 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (force_angle || (gl_info["version"].operator int() < 30003)) { tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); if (show_warning) { - WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE."); + if (gl_info["version"].operator int() < 30003) { + WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE."); + } else { + WARN_PRINT("Your video card drivers are known to have low quality OpenGL 3.3 support, switching to ANGLE."); + } } rendering_driver = "opengl3_angle"; } } + if (rendering_driver == "opengl3_angle") { + gl_manager_angle = memnew(GLManagerANGLE_Windows); + tested_drivers.set_flag(DRIVER_ID_COMPAT_ANGLE_D3D11); + + if (gl_manager_angle->initialize() != OK) { + memdelete(gl_manager_angle); + gl_manager_angle = nullptr; + bool fallback_to_native = GLOBAL_GET("rendering/gl_compatibility/fallback_to_native"); + if (fallback_to_native && gl_supported) { +#ifdef EGL_STATIC + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE, switching to native OpenGL."); +#else + WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dll and libGLESv2.dll) are missing, switching to native OpenGL."); +#endif + rendering_driver = "opengl3"; + } else { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Could not initialize ANGLE OpenGL."); + } + } + } if (rendering_driver == "opengl3") { gl_manager_native = memnew(GLManagerNative_Windows); tested_drivers.set_flag(DRIVER_ID_COMPAT_OPENGL3); @@ -6235,26 +6262,17 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win memdelete(gl_manager_native); gl_manager_native = nullptr; r_error = ERR_UNAVAILABLE; - return; + ERR_FAIL_MSG("Could not initialize native OpenGL."); } + } + if (rendering_driver == "opengl3") { RasterizerGLES3::make_current(true); } if (rendering_driver == "opengl3_angle") { - gl_manager_angle = memnew(GLManagerANGLE_Windows); - tested_drivers.set_flag(DRIVER_ID_COMPAT_ANGLE_D3D11); - - if (gl_manager_angle->initialize() != OK) { - memdelete(gl_manager_angle); - gl_manager_angle = nullptr; - r_error = ERR_UNAVAILABLE; - return; - } - RasterizerGLES3::make_current(false); } #endif - String appname; if (Engine::get_singleton()->is_editor_hint()) { appname = "Blazium.GodotEditor." + String(EXTERNAL_VERSION_FULL_CONFIG); From 022ab303c41f5ef3d674b0bd07746820f365c0db Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Wed, 21 Aug 2024 09:56:58 +0300 Subject: [PATCH 05/15] Update rendering driver name on fallbacks. Fix rendering driver/method in the editor system info. --- core/os/os.h | 6 ++--- editor/editor_node.cpp | 25 +++++++++++++++---- main/main.cpp | 9 +++---- .../wayland/display_server_wayland.cpp | 1 + platform/linuxbsd/x11/display_server_x11.cpp | 1 + platform/macos/display_server_macos.mm | 1 + platform/windows/display_server_windows.cpp | 3 +++ 7 files changed, 32 insertions(+), 14 deletions(-) diff --git a/core/os/os.h b/core/os/os.h index 91e0ce937944..22197d3517a4 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -111,9 +111,6 @@ class OS { virtual void initialize() = 0; virtual void initialize_joypads() = 0; - void set_current_rendering_driver_name(const String &p_driver_name) { _current_rendering_driver_name = p_driver_name; } - void set_current_rendering_method(const String &p_name) { _current_rendering_method = p_name; } - void set_display_driver_id(int p_display_driver_id) { _display_driver_id = p_display_driver_id; } virtual void set_main_loop(MainLoop *p_main_loop) = 0; @@ -131,6 +128,9 @@ class OS { static OS *get_singleton(); + void set_current_rendering_driver_name(const String &p_driver_name) { _current_rendering_driver_name = p_driver_name; } + void set_current_rendering_method(const String &p_name) { _current_rendering_method = p_name; } + String get_current_rendering_driver_name() const { return _current_rendering_driver_name; } String get_current_rendering_method() const { return _current_rendering_method; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index fa7f409ce2cf..db9555e24a53 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -172,6 +172,10 @@ #include "modules/modules_enabled.gen.h" // For gdscript, mono. +#if defined(GLES3_ENABLED) +#include "drivers/gles3/rasterizer_gles3.h" +#endif + EditorNode *EditorNode::singleton = nullptr; static const String EDITOR_NODE_CONFIG_SECTION = "EditorNode"; @@ -5018,8 +5022,8 @@ String EditorNode::_get_system_info() const { #ifdef LINUXBSD_ENABLED const String display_server = OS::get_singleton()->get_environment("XDG_SESSION_TYPE").capitalize().replace(" ", ""); // `replace` is necessary, because `capitalize` introduces a whitespace between "x" and "11". #endif // LINUXBSD_ENABLED - String driver_name = GLOBAL_GET("rendering/rendering_device/driver"); - String rendering_method = GLOBAL_GET("rendering/renderer/rendering_method"); + String driver_name = OS::get_singleton()->get_current_rendering_driver_name().to_lower(); + String rendering_method = OS::get_singleton()->get_current_rendering_method().to_lower(); const String rendering_device_name = RenderingServer::get_singleton()->get_video_adapter_name(); @@ -5055,12 +5059,23 @@ String EditorNode::_get_system_info() const { rendering_method = "Mobile"; } else if (rendering_method == "gl_compatibility") { rendering_method = "Compatibility"; - driver_name = GLOBAL_GET("rendering/gl_compatibility/driver"); } if (driver_name == "vulkan") { driver_name = "Vulkan"; - } else if (driver_name.begins_with("opengl3")) { - driver_name = "GLES3"; + } else if (driver_name == "d3d12") { + driver_name = "Direct3D 12"; +#if defined(GLES3_ENABLED) + } else if (driver_name == "opengl3_angle") { + driver_name = "OpenGL ES 3/ANGLE"; + } else if (driver_name == "opengl3_es") { + driver_name = "OpenGL ES 3"; + } else if (driver_name == "opengl3") { + if (RasterizerGLES3::is_gles_over_gl()) { + driver_name = "OpenGL 3"; + } else { + driver_name = "OpenGL ES 3"; + } +#endif } // Join info. diff --git a/main/main.cpp b/main/main.cpp index 3841eb6c1ee3..35ab8eb018a9 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2214,15 +2214,12 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph } } - // note this is the desired rendering driver, it doesn't mean we will get it. - // TODO - make sure this is updated in the case of fallbacks, so that the user interface - // shows the correct driver string. - OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); - OS::get_singleton()->set_current_rendering_method(rendering_method); - // always convert to lower case for consistency in the code rendering_driver = rendering_driver.to_lower(); + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); + OS::get_singleton()->set_current_rendering_method(rendering_method); + if (use_custom_res) { if (!force_res) { window_size.width = GLOBAL_GET("display/window/size/viewport_width"); diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index da4e1aa97cba..0e5e46d1528f 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1429,6 +1429,7 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (fallback) { WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES."); rendering_driver = "opengl3_es"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Could not initialize OpenGL."); diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index af4e3de71791..61576f7db3f1 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6231,6 +6231,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (fallback) { WARN_PRINT("Your video card drivers seem not to support the required OpenGL version, switching to OpenGLES."); rendering_driver = "opengl3_es"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Could not initialize OpenGL."); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 72f939a12d50..17d4e1711f3a 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3604,6 +3604,7 @@ WARN_PRINT("Your video card drivers seem not to support GLES3 / ANGLE or ANGLE dynamic libraries (libEGL.dylib and libGLESv2.dylib) are missing, switching to native OpenGL."); #endif rendering_driver = "opengl3"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Could not initialize ANGLE OpenGL."); diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 47dd3a096eaa..8a5c25c35a95 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6139,6 +6139,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Direct3D 12, switching to Vulkan."); rendering_driver = "vulkan"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); failed = false; } } @@ -6152,6 +6153,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win if (rendering_context->initialize() == OK) { WARN_PRINT("Your video card drivers seem not to support Vulkan, switching to Direct3D 12."); rendering_driver = "d3d12"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); failed = false; } } @@ -6230,6 +6232,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } rendering_driver = "opengl3_angle"; + OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } } From 72fab25068b43890d00caa35d30e122f4f93fb97 Mon Sep 17 00:00:00 2001 From: Riteo Date: Fri, 10 May 2024 01:44:57 +0200 Subject: [PATCH 06/15] Warn when falling back to another DisplayServer Before it was a bit unclear on what was happening, since a display server has to fail to fall back and so the user would be left with an error _and_ a (hopefully) running game. Should make the experience more pleasant on Linux/BSD now that we have two display servers. --- main/main.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/main/main.cpp b/main/main.cpp index 35ab8eb018a9..d7f69e34761a 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -2751,6 +2751,8 @@ Error Main::setup2(bool p_show_boot_logo) { Error err; display_server = DisplayServer::create(display_driver_idx, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, context, err); if (err != OK || display_server == nullptr) { + String last_name = DisplayServer::get_create_function_name(display_driver_idx); + // We can't use this display server, try other ones as fallback. // Skip headless (always last registered) because that's not what users // would expect if they didn't request it explicitly. @@ -2758,6 +2760,9 @@ Error Main::setup2(bool p_show_boot_logo) { if (i == display_driver_idx) { continue; // Don't try the same twice. } + String name = DisplayServer::get_create_function_name(i); + WARN_PRINT(vformat("Display driver %s failed, falling back to %s.", last_name, name)); + display_server = DisplayServer::create(i, rendering_driver, window_mode, window_vsync_mode, window_flags, window_position, window_size, init_screen, context, err); if (err == OK && display_server != nullptr) { break; From 35a888f70d9bb6642dde5f27a2f411bec0cce144 Mon Sep 17 00:00:00 2001 From: Riteo Date: Fri, 10 May 2024 02:04:22 +0200 Subject: [PATCH 07/15] X11: Alert only when video drivers fail initialization Before, they would always complain even if there was no attempt at initializing them (e.g. because there's no X11 display). While we're at it, this patch also adds a specific message for OpenGL ES and rewords "OpenGLES" to "OpenGL ES" in an error, for consistency (AFAIK we either say "GLES" or "OpenGL ES"). --- platform/linuxbsd/x11/display_server_x11.cpp | 75 ++++++++++++-------- 1 file changed, 45 insertions(+), 30 deletions(-) diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 61576f7db3f1..ead9b45f241c 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -5428,25 +5428,6 @@ Vector DisplayServerX11::get_rendering_drivers_func() { DisplayServer *DisplayServerX11::create_func(const String &p_rendering_driver, WindowMode p_mode, VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) { DisplayServer *ds = memnew(DisplayServerX11(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error)); - if (r_error != OK) { - if (p_rendering_driver == "vulkan") { - String executable_name = OS::get_singleton()->get_executable_path().get_file(); - 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"); - } else { - OS::get_singleton()->alert( - "Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" - "If possible, consider updating your video card drivers.\n\n" - "If you recently updated your video card drivers, try rebooting.", - "Unable to initialize OpenGL video driver"); - } - } return ds; } @@ -6160,25 +6141,40 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode rendering_driver = p_rendering_driver; bool driver_found = false; + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + + // Initialize context and rendering device. + #if defined(RD_ENABLED) #if defined(VULKAN_ENABLED) if (rendering_driver == "vulkan") { rendering_context = memnew(RenderingContextDriverVulkanX11); } -#endif +#endif // VULKAN_ENABLED if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Could not initialize %s", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; r_error = ERR_CANT_CREATE; - return; + + 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)); } driver_found = true; } -#endif - // Initialize context and rendering device. +#endif // RD_ENABLED + #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") { if (getenv("DRI_PRIME") == nullptr) { @@ -6234,6 +6230,16 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL video driver"); + ERR_FAIL_MSG("Could not initialize OpenGL."); } } else { @@ -6244,20 +6250,28 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (rendering_driver == "opengl3_es") { gl_manager_egl = memnew(GLManagerEGL_X11); - if (gl_manager_egl->initialize() != OK) { + if (gl_manager_egl->initialize() != OK || gl_manager_egl->open_display(x11_display) != OK) { memdelete(gl_manager_egl); gl_manager_egl = nullptr; r_error = ERR_UNAVAILABLE; - ERR_FAIL_MSG("Could not initialize OpenGLES."); + + OS::get_singleton()->alert( + "Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n" + "If possible, consider updating your video card drivers.\n\n" + "If you recently updated your video card drivers, try rebooting.", + "Unable to initialize OpenGL ES video driver"); + + ERR_FAIL_MSG("Could not initialize OpenGL ES."); } driver_found = true; RasterizerGLES3::make_current(false); } -#endif +#endif // GLES3_ENABLED + if (!driver_found) { r_error = ERR_UNAVAILABLE; - ERR_FAIL_MSG("Video driver not found"); + ERR_FAIL_MSG("Video driver not found."); } Point2i window_position; @@ -6298,7 +6312,7 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode RendererCompositorRD::make_current(); } -#endif +#endif // RD_ENABLED { //set all event master mask @@ -6451,7 +6465,8 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); portal_desktop = memnew(FreeDesktopPortalDesktop); -#endif +#endif // DBUS_ENABLED + XSetErrorHandler(&default_window_error_handler); r_error = OK; From 01fe3b89dda5c686eb4b7c942effdcbf108563bb Mon Sep 17 00:00:00 2001 From: Riteo Date: Fri, 10 May 2024 02:06:28 +0200 Subject: [PATCH 08/15] Wayland: report when video drivers can't be loaded or found This brings it to parity with the X11 backend. --- .../wayland/display_server_wayland.cpp | 59 ++++++++++++++++--- 1 file changed, 51 insertions(+), 8 deletions(-) diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 0e5e46d1528f..2e07f82720e3 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1349,23 +1349,39 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win rendering_driver = p_rendering_driver; + bool driver_found = false; + String executable_name = OS::get_singleton()->get_executable_path().get_file(); + #ifdef RD_ENABLED #ifdef VULKAN_ENABLED if (rendering_driver == "vulkan") { rendering_context = memnew(RenderingContextDriverVulkanWayland); } -#endif +#endif // VULKAN_ENABLED if (rendering_context) { if (rendering_context->initialize() != OK) { - ERR_PRINT(vformat("Could not initialize %s", rendering_driver)); memdelete(rendering_context); rendering_context = nullptr; r_error = ERR_CANT_CREATE; - return; + + 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)); } + + driver_found = true; } -#endif +#endif // RD_ENABLED #ifdef GLES3_ENABLED if (rendering_driver == "opengl3" || rendering_driver == "opengl3_es") { @@ -1432,26 +1448,53 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); } else { r_error = ERR_UNAVAILABLE; + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL 3.3 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL video driver"); + ERR_FAIL_MSG("Could not initialize OpenGL."); } } else { RasterizerGLES3::make_current(true); + driver_found = true; } } if (rendering_driver == "opengl3_es") { egl_manager = memnew(EGLManagerWaylandGLES); - if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK) { + if (egl_manager->initialize(wayland_thread.get_wl_display()) != OK || egl_manager->open_display(wayland_thread.get_wl_display()) != OK) { memdelete(egl_manager); egl_manager = nullptr; r_error = ERR_CANT_CREATE; - ERR_FAIL_MSG("Could not initialize GLES3."); + + OS::get_singleton()->alert( + vformat("Your video card drivers seem not to support the required OpenGL ES 3.0 version.\n\n" + "If possible, consider updating your video card drivers or using the Vulkan driver.\n\n" + "You can enable the Vulkan driver by starting the engine from the\n" + "command line with the command:\n\n \"%s\" --rendering-driver vulkan\n\n" + "If you recently updated your video card drivers, try rebooting.", + executable_name), + "Unable to initialize OpenGL ES video driver"); + + ERR_FAIL_MSG("Could not initialize OpenGL ES."); } RasterizerGLES3::make_current(false); + driver_found = true; } } + + if (!driver_found) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Video driver not found."); + } #endif // GLES3_ENABLED cursor_set_shape(CURSOR_BUSY); @@ -1482,12 +1525,12 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win RendererCompositorRD::make_current(); } -#endif +#endif // RD_ENABLED #ifdef DBUS_ENABLED portal_desktop = memnew(FreeDesktopPortalDesktop); screensaver = memnew(FreeDesktopScreenSaver); -#endif +#endif // DBUS_ENABLED screen_set_keep_on(GLOBAL_GET("display/window/energy_saving/keep_screen_on")); From 480d18be9d163bd84ea9c33e8adddc219787f119 Mon Sep 17 00:00:00 2001 From: SheepYhangCN Date: Wed, 18 Sep 2024 19:10:59 +0800 Subject: [PATCH 09/15] Added fallback_to_opengl3 --- doc/classes/ProjectSettings.xml | 4 +++ main/main.cpp | 1 + platform/android/display_server_android.cpp | 14 +++++++-- platform/ios/display_server_ios.mm | 14 +++++++-- platform/linuxbsd/x11/display_server_x11.cpp | 32 ++++++++++++-------- platform/macos/display_server_macos.mm | 12 ++++++-- platform/windows/display_server_windows.cpp | 11 +++++++ 7 files changed, 68 insertions(+), 20 deletions(-) diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml index f1fe9c38f691..aceafa2a16d6 100644 --- a/doc/classes/ProjectSettings.xml +++ b/doc/classes/ProjectSettings.xml @@ -2790,6 +2790,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 d7f69e34761a..86427b5d44f7 100644 --- a/main/main.cpp +++ b/main/main.cpp @@ -1963,6 +1963,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 b88d887af52c..c1053215c694 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 802fbefc0dbb..f29cfcdb13a6 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -88,11 +88,19 @@ 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 ead9b45f241c..7b651ee9c4d3 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6156,20 +6156,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 17d4e1711f3a..301b5df2856b 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3633,8 +3633,16 @@ 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 8a5c25c35a95..bfa62864e068 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6158,6 +6158,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; From 1d121af926b5008be031b795499c6833761f0918 Mon Sep 17 00:00:00 2001 From: Joaquim Monteiro Date: Sat, 21 Sep 2024 06:35:35 +0100 Subject: [PATCH 10/15] Fallback to OpenGL 3 if Vulkan isn't available on Wayland --- .../wayland/display_server_wayland.cpp | 32 ++++++++++++------- 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 2e07f82720e3..5f47af5e7949 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1363,20 +1363,28 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win 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; From e2320b4708d927074989bfa9860b9666402f98d9 Mon Sep 17 00:00:00 2001 From: Shatyuka Date: Fri, 3 May 2024 06:36:51 +0800 Subject: [PATCH 11/15] Apply `WS_MINIMIZE` style on window creation --- platform/windows/display_server_windows.cpp | 28 +++++++++++++++------ platform/windows/display_server_windows.h | 4 ++- 2 files changed, 23 insertions(+), 9 deletions(-) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index bfa62864e068..003040cd1b77 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1501,6 +1501,7 @@ DisplayServer::WindowID DisplayServerWindows::create_sub_window(WindowMode p_mod rendering_device->screen_create(window_id); } #endif + wd.initialized = true; return window_id; } @@ -2039,7 +2040,7 @@ Size2i DisplayServerWindows::window_get_size_with_decorations(WindowID p_window) return Size2(); } -void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) { +void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_initialized, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_minimized, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex) { // Windows docs for window styles: // https://docs.microsoft.com/en-us/windows/win32/winmsg/window-styles // https://docs.microsoft.com/en-us/windows/win32/winmsg/extended-window-styles @@ -2048,12 +2049,16 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre r_style_ex = WS_EX_WINDOWEDGE; if (p_main_window) { r_style_ex |= WS_EX_APPWINDOW; - r_style |= WS_VISIBLE; + if (p_initialized) { + r_style |= WS_VISIBLE; + } } if (p_fullscreen || p_borderless) { r_style |= WS_POPUP; // p_borderless was WS_EX_TOOLWINDOW in the past. - if (p_maximized) { + if (p_minimized) { + r_style |= WS_MINIMIZE; + } else if (p_maximized) { r_style |= WS_MAXIMIZE; } if (!p_fullscreen) { @@ -2068,13 +2073,19 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre } } else { if (p_resizable) { - if (p_maximized) { + if (p_minimized) { + r_style = WS_OVERLAPPEDWINDOW | WS_MINIMIZE; + } else if (p_maximized) { r_style = WS_OVERLAPPEDWINDOW | WS_MAXIMIZE; } else { r_style = WS_OVERLAPPEDWINDOW; } } else { - r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + if (p_minimized) { + r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MINIMIZE; + } else { + r_style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + } } } @@ -2082,7 +2093,7 @@ void DisplayServerWindows::_get_window_style(bool p_main_window, bool p_fullscre r_style_ex |= WS_EX_TOPMOST | WS_EX_NOACTIVATE; } - if (!p_borderless && !p_no_activate_focus) { + if (!p_borderless && !p_no_activate_focus && p_initialized) { r_style |= WS_VISIBLE; } @@ -2099,7 +2110,7 @@ void DisplayServerWindows::_update_window_style(WindowID p_window, bool p_repain DWORD style = 0; DWORD style_ex = 0; - _get_window_style(p_window == MAIN_WINDOW_ID, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.maximized, wd.maximized_fs, wd.no_focus || wd.is_popup, style, style_ex); + _get_window_style(p_window == MAIN_WINDOW_ID, wd.initialized, wd.fullscreen, wd.multiwindow_fs, wd.borderless, wd.resizable, wd.minimized, wd.maximized, wd.maximized_fs, wd.no_focus || wd.is_popup, style, style_ex); SetWindowLongPtr(wd.hWnd, GWL_STYLE, style); SetWindowLongPtr(wd.hWnd, GWL_EXSTYLE, style_ex); @@ -5510,7 +5521,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, DWORD dwExStyle; DWORD dwStyle; - _get_window_style(window_id_counter == MAIN_WINDOW_ID, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); + _get_window_style(window_id_counter == MAIN_WINDOW_ID, false, (p_mode == WINDOW_MODE_FULLSCREEN || p_mode == WINDOW_MODE_EXCLUSIVE_FULLSCREEN), p_mode != WINDOW_MODE_EXCLUSIVE_FULLSCREEN, p_flags & WINDOW_FLAG_BORDERLESS_BIT, !(p_flags & WINDOW_FLAG_RESIZE_DISABLED_BIT), p_mode == WINDOW_MODE_MINIMIZED, p_mode == WINDOW_MODE_MAXIMIZED, false, (p_flags & WINDOW_FLAG_NO_FOCUS_BIT) | (p_flags & WINDOW_FLAG_POPUP), dwStyle, dwExStyle); RECT WindowRect; @@ -6342,6 +6353,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } + windows[MAIN_WINDOW_ID].initialized = true; show_window(MAIN_WINDOW_ID); #if defined(RD_ENABLED) diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index 54e1c9681ddc..7d6a3e96a6bc 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -524,6 +524,8 @@ class DisplayServerWindows : public DisplayServer { bool is_popup = false; Rect2i parent_safe_rect; + + bool initialized = false; }; JoypadWindows *joypad = nullptr; @@ -591,7 +593,7 @@ class DisplayServerWindows : public DisplayServer { HashMap pointer_last_pos; void _send_window_event(const WindowData &wd, WindowEvent p_event); - void _get_window_style(bool p_main_window, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex); + void _get_window_style(bool p_main_window, bool p_initialized, bool p_fullscreen, bool p_multiwindow_fs, bool p_borderless, bool p_resizable, bool p_minimized, bool p_maximized, bool p_maximized_fs, bool p_no_activate_focus, DWORD &r_style, DWORD &r_style_ex); MouseMode mouse_mode; int restore_mouse_trails = 0; From 65a10ae988fe8e8c881f36535cfe486ef8214c03 Mon Sep 17 00:00:00 2001 From: bruvzg <7645683+bruvzg@users.noreply.github.com> Date: Thu, 3 Oct 2024 10:38:32 +0300 Subject: [PATCH 12/15] Fix window_set_current_screen for maximized windows. --- platform/linuxbsd/x11/display_server_x11.cpp | 2 +- platform/macos/display_server_macos.mm | 10 ++++++++++ platform/windows/display_server_windows.cpp | 7 +++++++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index 7b651ee9c4d3..b6dba87a72f1 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -2055,7 +2055,7 @@ void DisplayServerX11::window_set_current_screen(int p_screen, WindowID p_window return; } - if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN) { + if (window_get_mode(p_window) == WINDOW_MODE_FULLSCREEN || window_get_mode(p_window) == WINDOW_MODE_MAXIMIZED) { Point2i position = screen_get_position(p_screen); Size2i size = screen_get_size(p_screen); diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 301b5df2856b..16502e79ff74 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -1885,6 +1885,12 @@ was_fullscreen = true; } + bool was_maximized = false; + if (!was_fullscreen && NSEqualRects([wd.window_object frame], [[wd.window_object screen] visibleFrame])) { + [wd.window_object zoom:nil]; + was_maximized = true; + } + Rect2i srect = screen_get_usable_rect(p_screen); Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); Size2i wsize = window_get_size(p_window); @@ -1893,6 +1899,10 @@ wpos = wpos.clamp(srect.position, srect.position + srect.size - wsize / 3); window_set_position(wpos, p_window); + if (was_maximized) { + [wd.window_object zoom:nil]; + } + if (was_fullscreen) { // Re-enter fullscreen mode. [wd.window_object toggleFullScreen:nil]; diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 003040cd1b77..ba4fbd224b58 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -1795,6 +1795,13 @@ void DisplayServerWindows::window_set_current_screen(int p_screen, WindowID p_wi Size2 size = screen_get_size(p_screen); MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); + } else if (wd.maximized) { + Point2 pos = screen_get_position(p_screen) + _get_screens_origin(); + Size2 size = screen_get_size(p_screen); + + ShowWindow(wd.hWnd, SW_RESTORE); + MoveWindow(wd.hWnd, pos.x, pos.y, size.width, size.height, TRUE); + ShowWindow(wd.hWnd, SW_MAXIMIZE); } else { Rect2i srect = screen_get_usable_rect(p_screen); Point2i wpos = window_get_position(p_window) - screen_get_position(window_get_current_screen(p_window)); From 6564550e47be86ce85691c6e39682d4a93501e0f Mon Sep 17 00:00:00 2001 From: "Matias N. Goldberg" Date: Sat, 12 Oct 2024 20:20:12 -0300 Subject: [PATCH 13/15] Fix wrong Wayland path if building with opengl3=no Godot checks if there's Vulkan or GLES3 support. If no support is found, it shows an error message. However the code for this error message is left out when building with opengl3=no --- platform/linuxbsd/wayland/display_server_wayland.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 5f47af5e7949..80e0cda06068 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1498,12 +1498,12 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win driver_found = true; } } +#endif // GLES3_ENABLED if (!driver_found) { r_error = ERR_UNAVAILABLE; ERR_FAIL_MSG("Video driver not found."); } -#endif // GLES3_ENABLED cursor_set_shape(CURSOR_BUSY); From f589647a4ce3ccdf3fe68f295b0dafec10f6f3b7 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 21 Oct 2024 17:18:43 -0700 Subject: [PATCH 14/15] Fix window exiting with no message to user if _create_window fails --- platform/windows/display_server_windows.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index ba4fbd224b58..9c1b757891e9 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6350,7 +6350,10 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } WindowID main_window = _create_window(p_mode, p_vsync_mode, p_flags, Rect2i(window_position, p_resolution), false, INVALID_WINDOW_ID); - ERR_FAIL_COND_MSG(main_window == INVALID_WINDOW_ID, "Failed to create main window."); + if (main_window == INVALID_WINDOW_ID) { + r_error = ERR_UNAVAILABLE; + ERR_FAIL_MSG("Failed to create main window."); + } joypad = new JoypadWindows(&windows[MAIN_WINDOW_ID].hWnd); From 5e53efcc169138a6d6b5603b0f8d3412fc2b746c Mon Sep 17 00:00:00 2001 From: Mounir Tohami <53877170+WhalesState@users.noreply.github.com> Date: Tue, 3 Dec 2024 12:38:54 +0200 Subject: [PATCH 15/15] Fix fallbacks to OpenGL --- platform/android/display_server_android.cpp | 19 ++++--- .../lib/src/org/godotengine/godot/Godot.kt | 18 +++++-- platform/ios/display_server_ios.mm | 7 ++- .../wayland/display_server_wayland.cpp | 5 +- platform/linuxbsd/x11/display_server_x11.cpp | 5 +- platform/macos/display_server_macos.mm | 52 ++++++++++--------- platform/windows/display_server_windows.cpp | 2 + 7 files changed, 71 insertions(+), 37 deletions(-) diff --git a/platform/android/display_server_android.cpp b/platform/android/display_server_android.cpp index c1053215c694..145f9784fd01 100644 --- a/platform/android/display_server_android.cpp +++ b/platform/android/display_server_android.cpp @@ -589,12 +589,6 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis native_menu = memnew(NativeMenu); -#if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { - RasterizerGLES3::make_current(false); - } -#endif - #if defined(RD_ENABLED) rendering_context = nullptr; rendering_device = nullptr; @@ -609,19 +603,24 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; +#if defined(GLES3_ENABLED) 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 { + } else +#endif + { ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); r_error = ERR_UNAVAILABLE; return; } } + } + if (rendering_context) { union { #ifdef VULKAN_ENABLED RenderingContextDriverVulkanAndroid::WindowPlatformData vulkan; @@ -661,6 +660,12 @@ DisplayServerAndroid::DisplayServerAndroid(const String &p_rendering_driver, Dis } #endif +#if defined(GLES3_ENABLED) + if (rendering_driver == "opengl3") { + RasterizerGLES3::make_current(false); + } +#endif + Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events); r_error = OK; diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt index eaa79163fb50..4e0ee85773df 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.kt @@ -473,12 +473,17 @@ class Godot(private val context: Context) { // ...add to FrameLayout containerLayout?.addView(editText) renderView = if (usesVulkan()) { - if (!meetsVulkanRequirements(activity.packageManager)) { + if (meetsVulkanRequirements(activity.packageManager)) { + GodotVulkanRenderView(host, this, godotInputHandler) + } else if (canFallbackToOpenGL()) { + // Fallback to OpenGl. + GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl) + } else { throw IllegalStateException(activity.getString(R.string.error_missing_vulkan_requirements_message)) } - GodotVulkanRenderView(host, this, godotInputHandler) + } else { - // Fallback to openGl + // Fallback to OpenGl. GodotGLRenderView(host, this, godotInputHandler, xrMode, useDebugOpengl) } @@ -812,6 +817,13 @@ class Godot(private val context: Context) { return ("forward_plus" == renderer || "mobile" == renderer) && "vulkan" == renderingDevice } + /** + * Returns true if can fallback to OpenGL. + */ + private fun canFallbackToOpenGL(): Boolean { + return java.lang.Boolean.parseBoolean(GodotLib.getGlobal("rendering/rendering_device/fallback_to_opengl3")) + } + /** * Returns true if the device meets the base requirements for Vulkan support, false otherwise. */ diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm index f29cfcdb13a6..600fee75b35f 100644 --- a/platform/ios/display_server_ios.mm +++ b/platform/ios/display_server_ios.mm @@ -90,19 +90,24 @@ if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; +#if defined(GLES3_ENABLED) 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 { + } else +#endif + { ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver)); r_error = ERR_UNAVAILABLE; return; } } + } + if (rendering_context) { if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) { ERR_PRINT(vformat("Failed to create %s window.", rendering_driver)); memdelete(rendering_context); diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index 80e0cda06068..d5b1c67550ea 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -1363,13 +1363,16 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; +#if defined(GLES3_ENABLED) 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 { + } else +#endif // GLES3_ENABLED + { r_error = ERR_CANT_CREATE; if (p_rendering_driver == "vulkan") { diff --git a/platform/linuxbsd/x11/display_server_x11.cpp b/platform/linuxbsd/x11/display_server_x11.cpp index b6dba87a72f1..4071f9dea173 100644 --- a/platform/linuxbsd/x11/display_server_x11.cpp +++ b/platform/linuxbsd/x11/display_server_x11.cpp @@ -6156,13 +6156,16 @@ DisplayServerX11::DisplayServerX11(const String &p_rendering_driver, WindowMode if (rendering_context->initialize() != OK) { memdelete(rendering_context); rendering_context = nullptr; +#if defined(GLES3_ENABLED) 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 { + } else +#endif // GLES3_ENABLED + { r_error = ERR_CANT_CREATE; if (p_rendering_driver == "vulkan") { diff --git a/platform/macos/display_server_macos.mm b/platform/macos/display_server_macos.mm index 16502e79ff74..51f5ea6c0791 100644 --- a/platform/macos/display_server_macos.mm +++ b/platform/macos/display_server_macos.mm @@ -3600,6 +3600,34 @@ //TODO - do Vulkan and OpenGL support checks, driver selection and fallback rendering_driver = p_rendering_driver; +#if defined(RD_ENABLED) +#if defined(VULKAN_ENABLED) + if (rendering_driver == "vulkan") { + rendering_context = memnew(RenderingContextDriverVulkanMacOS); + } +#endif + + if (rendering_context) { + if (rendering_context->initialize() != OK) { + memdelete(rendering_context); + rendering_context = nullptr; +#if defined(GLES3_ENABLED) + 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 +#endif + { + r_error = ERR_CANT_CREATE; + ERR_FAIL_MSG("Could not initialize " + rendering_driver); + } + } + } +#endif + #if defined(GLES3_ENABLED) if (rendering_driver == "opengl3_angle") { gl_manager_angle = memnew(GLManagerANGLE_MacOS); @@ -3632,30 +3660,6 @@ } } #endif -#if defined(RD_ENABLED) -#if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - rendering_context = memnew(RenderingContextDriverVulkanMacOS); - } -#endif - - if (rendering_context) { - if (rendering_context->initialize() != OK) { - memdelete(rendering_context); - rendering_context = nullptr; - 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 Point2i window_position; if (p_position != nullptr) { diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 9c1b757891e9..cf8a39341d78 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -6176,6 +6176,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win } } #endif +#if defined(GLES3_ENABLED) bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3"); if (failed && fallback_to_opengl3 && rendering_driver != "opengl3") { memdelete(rendering_context); @@ -6187,6 +6188,7 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win OS::get_singleton()->set_current_rendering_driver_name(rendering_driver); failed = false; } +#endif if (failed) { memdelete(rendering_context); rendering_context = nullptr;