Skip to content

Commit

Permalink
Merge pull request #171 from WhalesState/fix-running-blazium-on-block…
Browse files Browse the repository at this point in the history
…ed-GPUs

Fix running Blazium on blocked GPUs.
  • Loading branch information
jss2a98aj authored Dec 4, 2024
2 parents 94a7dd7 + 5e53efc commit 932319a
Show file tree
Hide file tree
Showing 19 changed files with 465 additions and 135 deletions.
6 changes: 3 additions & 3 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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; }

Expand Down
8 changes: 6 additions & 2 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2526,8 +2526,8 @@
[b]Note:[/b] This setting is implemented only on Linux/X11.
</member>
<member name="rendering/gl_compatibility/fallback_to_native" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="rendering/gl_compatibility/force_angle_on_devices" type="Array" setter="" getter="">
An [Array] of devices which should always use the ANGLE renderer.
Expand Down Expand Up @@ -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.
</member>
<member name="rendering/rendering_device/fallback_to_opengl3" type="bool" setter="" getter="" default="true">
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.
</member>
<member name="rendering/rendering_device/fallback_to_vulkan" type="bool" setter="" getter="" default="true">
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.
Expand Down
1 change: 0 additions & 1 deletion drivers/d3d12/SCsub
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ if env.msvc:
]
else:
extra_defines += [
("__REQUIRED_RPCNDR_H_VERSION__", 475),
"HAVE_STRUCT_TIMESPEC",
]

Expand Down
5 changes: 5 additions & 0 deletions drivers/d3d12/rendering_device_driver_d3d12.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 2 additions & 2 deletions drivers/egl/egl_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 20 additions & 5 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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.
Expand Down
32 changes: 29 additions & 3 deletions editor/project_manager/project_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -444,30 +444,41 @@ 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.") +
String::utf8("\n") + TTR("Advanced 3D graphics available.") +
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.") +
String::utf8("\n") + TTR("Less advanced 3D graphics.") +
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() {
Expand Down Expand Up @@ -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");
Expand All @@ -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");
Expand Down Expand Up @@ -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);
Expand Down
2 changes: 2 additions & 0 deletions editor/project_manager/project_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ class ProjectDialog : public ConfirmationDialog {
Label *renderer_info = nullptr;
HBoxContainer *default_files_container = nullptr;
Ref<ButtonGroup> renderer_button_group;
bool rendering_device_supported = false;
Label *rd_not_supported = nullptr;

Label *msg = nullptr;
LineEdit *project_name = nullptr;
Expand Down
15 changes: 9 additions & 6 deletions main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

{
Expand Down Expand Up @@ -2214,15 +2215,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");
Expand Down Expand Up @@ -2754,13 +2752,18 @@ 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.
for (int i = 0; i < DisplayServer::get_create_function_count() - 1; i++) {
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;
Expand Down
31 changes: 22 additions & 9 deletions platform/android/display_server_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -607,13 +601,26 @@ 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;
#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
#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;
Expand Down Expand Up @@ -653,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;
Expand Down
18 changes: 15 additions & 3 deletions platform/android/java/lib/src/org/godotengine/godot/Godot.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down Expand Up @@ -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.
*/
Expand Down
19 changes: 16 additions & 3 deletions platform/ios/display_server_ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -88,13 +88,26 @@

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;
#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
{
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);
Expand Down
Loading

0 comments on commit 932319a

Please sign in to comment.