From d0276b3c649f40323602081835ea49d07195b1ae Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Fri, 2 Aug 2024 17:37:45 +0200 Subject: [PATCH] Warn in the editor and startup header when using software rendering Software rendering is very slow and is meant to be used for automated testing only (on servers without a GPU). `--no-header` skips the startup warning if specified on the command line. --- doc/classes/RenderingServer.xml | 3 ++- drivers/gles3/rasterizer_gles3.cpp | 5 +++++ drivers/gles3/storage/utilities.cpp | 7 +++++++ editor/editor_node.cpp | 22 ++++++++++++++++++++++ servers/rendering/rendering_device.cpp | 16 ++++++++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/doc/classes/RenderingServer.xml b/doc/classes/RenderingServer.xml index 3c9f0fc7aff..bef1c855098 100644 --- a/doc/classes/RenderingServer.xml +++ b/doc/classes/RenderingServer.xml @@ -1609,7 +1609,8 @@ Returns the type of the video adapter. Since dedicated graphics cards from a given generation will [i]usually[/i] be significantly faster than integrated graphics made in the same generation, the device type can be used as a basis for automatic graphics settings adjustment. However, this is not always true, so make sure to provide users with a way to manually override graphics settings. - [b]Note:[/b] When using the OpenGL backend or when running in headless mode, this function always returns [constant RenderingDevice.DEVICE_TYPE_OTHER]. + [b]Note:[/b] When running the OpenGL driver, this function returns [constant RenderingDevice.DEVICE_TYPE_CPU] for software-emulated GPUs (such as llvmpipe) and [constant RenderingDevice.DEVICE_TYPE_OTHER] for all other device types. The detection is based on the video adapter name, as OpenGL does not have an actual API for querying the current device type. + [b]Note:[/b] When running in headless mode, this function always returns [constant RenderingDevice.DEVICE_TYPE_OTHER]. diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp index 37e7256d764..0cad3a98b5d 100644 --- a/drivers/gles3/rasterizer_gles3.cpp +++ b/drivers/gles3/rasterizer_gles3.cpp @@ -194,6 +194,11 @@ typedef void(GLAPIENTRY *DebugMessageCallbackARB)(DEBUGPROCARB callback, const v void RasterizerGLES3::initialize() { Engine::get_singleton()->print_header(vformat("OpenGL API %s - Compatibility - Using Device: %s - %s", RS::get_singleton()->get_video_adapter_api_version(), RS::get_singleton()->get_video_adapter_vendor(), RS::get_singleton()->get_video_adapter_name())); + if (RS::get_singleton()->get_video_adapter_type() == RenderingDevice::DEVICE_TYPE_CPU) { + Engine::get_singleton()->print_header_rich( + "[color=yellow][b]WARNING:[/b] OpenGL is currently running on software emulation, which is very slow. Check whether your GPU supports OpenGL and make sure its drivers are up-to-date."); + } + // FLIP XY Bug: Are more devices affected? // Confirmed so far: all Adreno 3xx with old driver (until 2018) // ok on some tested Adreno devices: 4xx, 5xx and 6xx diff --git a/drivers/gles3/storage/utilities.cpp b/drivers/gles3/storage/utilities.cpp index 7f0be364663..3356dffebb5 100644 --- a/drivers/gles3/storage/utilities.cpp +++ b/drivers/gles3/storage/utilities.cpp @@ -454,6 +454,13 @@ String Utilities::get_video_adapter_vendor() const { } RenderingDevice::DeviceType Utilities::get_video_adapter_type() const { + // Detect common OpenGL software rasterizers according to the reported GPU model name. + // See . + const String adapter_name = get_video_adapter_name().to_lower(); + if (adapter_name.contains("llvmpipe") || adapter_name.contains("softpipe") || adapter_name.contains("swr")) { + return RenderingDevice::DeviceType::DEVICE_TYPE_CPU; + } + return RenderingDevice::DeviceType::DEVICE_TYPE_OTHER; } diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp index 8b6d316dd16..db6c629b554 100644 --- a/editor/editor_node.cpp +++ b/editor/editor_node.cpp @@ -723,6 +723,28 @@ void EditorNode::_notification(int p_what) { CanvasItemEditor::ThemePreviewMode theme_preview_mode = (CanvasItemEditor::ThemePreviewMode)(int)EditorSettings::get_singleton()->get_project_metadata("2d_editor", "theme_preview", CanvasItemEditor::THEME_PREVIEW_PROJECT); update_preview_themes(theme_preview_mode); + if (RenderingDevice::get_singleton() && RenderingDevice::get_singleton()->get_device_type() == RenderingDevice::DEVICE_TYPE_CPU) { + const String driver_name = OS::get_singleton()->get_current_rendering_driver_name(); + String driver_friendly_name; + if (driver_name == "d3d12") { + driver_friendly_name = "Direct3D 12"; + } else if (driver_name == "metal") { + driver_friendly_name = "Metal"; + } else { + driver_friendly_name = "Vulkan"; + } + log->add_message( + vformat(TTR("%s is currently running on software emulation, which is very slow. Check whether your GPU supports %s and make sure its drivers are up-to-date.\nIf your GPU is not compatible with %s, try switching to the Compatibility rendering method in the top-right corner of the editor."), + driver_friendly_name, + driver_friendly_name, + driver_friendly_name), + EditorLog::MSG_TYPE_WARNING); + } else if (RenderingServer::get_singleton()->get_video_adapter_type() == RenderingDevice::DEVICE_TYPE_CPU) { + log->add_message( + TTR("OpenGL is currently running on software emulation, which is very slow. Check whether your GPU supports OpenGL and make sure its drivers are up-to-date.\nIf your GPU is not compatible with OpenGL, try switching to the Forward+ or Mobile rendering methods in the top-right corner of the editor."), + EditorLog::MSG_TYPE_WARNING); + } + /* DO NOT LOAD SCENES HERE, WAIT FOR FILE SCANNING AND REIMPORT TO COMPLETE */ } break; diff --git a/servers/rendering/rendering_device.cpp b/servers/rendering/rendering_device.cpp index 22044a8c2d1..b086dd5fa29 100644 --- a/servers/rendering/rendering_device.cpp +++ b/servers/rendering/rendering_device.cpp @@ -5382,6 +5382,22 @@ Error RenderingDevice::initialize(RenderingContextDriver *p_context, DisplayServ // Output our device version. Engine::get_singleton()->print_header(vformat("%s %s - %s - Using Device #%d: %s - %s", get_device_api_name(), get_device_api_version(), rendering_method, device_index, _get_device_vendor_name(device), device.name)); + + if (get_device_type() == DEVICE_TYPE_CPU) { + const String driver_name = OS::get_singleton()->get_current_rendering_driver_name(); + String driver_friendly_name; + if (driver_name == "d3d12") { + driver_friendly_name = "Direct3D 12"; + } else if (driver_name == "metal") { + driver_friendly_name = "Metal"; + } else { + driver_friendly_name = "Vulkan"; + } + Engine::get_singleton()->print_header_rich( + vformat("[color=yellow][b]WARNING:[/b] %s is currently running on software emulation, which is very slow. Check whether your GPU supports %s and make sure its drivers are up-to-date.", + driver_friendly_name, + driver_friendly_name)); + } } // Pick the main queue family. It is worth noting we explicitly do not request the transfer bit, as apparently the specification defines