Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ANGLE] Add fallback control options and defaults. #82364

Merged
merged 1 commit into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2366,6 +2366,13 @@
<member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default="&quot;opengl3&quot;">
Windows override for [member rendering/gl_compatibility/driver].
</member>
<member name="rendering/gl_compatibility/fallback_to_angle" type="bool" setter="" getter="" default="true">
If [code]true[/code], the compatibility renderer will fall back to ANGLE if native OpenGL is not supported or the device is listed in [member rendering/gl_compatibility/force_angle_on_devices].
</member>
<member name="rendering/gl_compatibility/force_angle_on_devices" type="Array" setter="" getter="" default="[]">
An [Array] of devices which should always use the ANGLE renderer.
Each entry is a [Dictionary] with the following keys: [code]vendor[/code] and [code]name[/code]. [code]name[/code] can be set to [code]*[/code] to add all devices with the specified [code]vendor[/code].
</member>
<member name="rendering/gl_compatibility/item_buffer_size" type="int" setter="" getter="" default="16384">
Maximum number of canvas items commands that can be drawn in a single viewport update. If more render commands are issued they will be ignored. Decreasing this limit may improve performance on bandwidth limited devices. Increase this limit if you find that not all objects are being drawn in a frame.
</member>
Expand Down
9 changes: 8 additions & 1 deletion main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1752,15 +1752,22 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
#endif

String default_driver = driver_hints.get_slice(",", 0);
String default_driver_macos = default_driver;
#if defined(GLES3_ENABLED) && defined(EGL_STATIC) && defined(MACOS_ENABLED)
default_driver_macos = "opengl3_angle"; // Default to ANGLE if it's built-in.
#endif

GLOBAL_DEF_RST("rendering/gl_compatibility/driver", default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.linuxbsd", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.web", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.android", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.ios", PROPERTY_HINT_ENUM, driver_hints), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver);
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/gl_compatibility/driver.macos", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver_macos);
GLOBAL_DEF_RST("rendering/gl_compatibility/nvidia_disable_threaded_optimization", true);
GLOBAL_DEF_RST("rendering/gl_compatibility/fallback_to_angle", true);

GLOBAL_DEF_RST(PropertyInfo(Variant::ARRAY, "rendering/gl_compatibility/force_angle_on_devices", PROPERTY_HINT_ARRAY_TYPE, vformat("%s/%s:%s", Variant::DICTIONARY, PROPERTY_HINT_NONE, String())), Array());
}

// Start with RenderingDevice-based backends. Should be included if any RD driver present.
Expand Down
19 changes: 16 additions & 3 deletions platform/windows/display_server_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4579,9 +4579,22 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
// Init context and rendering device
#if defined(GLES3_ENABLED)

if (rendering_driver == "opengl3") {
int gl_version = detect_wgl_version();
if (gl_version < 30003) {
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_angle");
if (fallback && (rendering_driver == "opengl3")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we still need a path to check for gl_version support when not using the fallback? This seems like it will fail for devices that don't have the fallback enabled and don't support the required version

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems like it will fail for devices that don't have the fallback enabled and don't support the required version

Isn't it what is supposed to do in such case?

Dictionary gl_info = detect_wgl();

bool force_angle = false;

Array device_list = GLOBAL_GET("rendering/gl_compatibility/force_angle_on_devices");
for (int i = 0; i < device_list.size(); i++) {
const Dictionary &device = device_list[i];
if (device.has("vendor") && device.has("name") && device["vendor"].operator String().to_upper() == gl_info["vendor"].operator String().to_upper() && (device["name"] == "*" || device["name"].operator String().to_upper() == gl_info["name"].operator String().to_upper())) {
force_angle = true;
break;
}
}

if (force_angle || (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.");
rendering_driver = "opengl3_angle";
}
Expand Down
24 changes: 16 additions & 8 deletions platform/windows/wgl_detect_version.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "core/string/print_string.h"
#include "core/string/ustring.h"
#include "core/variant/dictionary.h"

#include <windows.h>

Expand Down Expand Up @@ -64,9 +65,11 @@ typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int
typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
typedef const char *(APIENTRY *PFNWGLGETSTRINGPROC)(unsigned int);

int detect_wgl_version() {
int major = 0;
int minor = 0;
Dictionary detect_wgl() {
Dictionary gl_info;
gl_info["version"] = 0;
gl_info["vendor"] = String();
gl_info["name"] = String();

PFNWGLCREATECONTEXT gd_wglCreateContext;
PFNWGLMAKECURRENT gd_wglMakeCurrent;
Expand All @@ -75,14 +78,14 @@ int detect_wgl_version() {

HMODULE module = LoadLibraryW(L"opengl32.dll");
if (!module) {
return 0;
return gl_info;
}
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
return 0;
return gl_info;
}

LPCWSTR class_name = L"EngineWGLDetect";
Expand Down Expand Up @@ -151,21 +154,26 @@ int detect_wgl_version() {
};
const char *version = (const char *)gd_wglGetString(WGL_VERSION);
if (version) {
const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).strip_edges();
const String device_name = String::utf8((const char *)gd_wglGetString(WGL_RENDERER)).strip_edges();
const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).strip_edges().trim_suffix(" Corporation");
const String device_name = String::utf8((const char *)gd_wglGetString(WGL_RENDERER)).strip_edges().trim_suffix("/PCIe/SSE2");
for (int i = 0; prefixes[i]; i++) {
size_t length = strlen(prefixes[i]);
if (strncmp(version, prefixes[i], length) == 0) {
version += length;
break;
}
}
int major = 0;
int minor = 0;
#ifdef _MSC_VER
sscanf_s(version, "%d.%d", &major, &minor);
#else
sscanf(version, "%d.%d", &major, &minor);
#endif
print_verbose(vformat("Native OpenGL API detected: %d.%d: %s - %s", major, minor, device_vendor, device_name));
gl_info["vendor"] = device_vendor;
gl_info["name"] = device_name;
gl_info["version"] = major * 10000 + minor;
}
}
}
Expand All @@ -183,7 +191,7 @@ int detect_wgl_version() {
}
UnregisterClassW(class_name, hInstance);

return major * 10000 + minor;
return gl_info;
}

#endif // WINDOWS_ENABLED && GLES3_ENABLED
4 changes: 3 additions & 1 deletion platform/windows/wgl_detect_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@

#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)

int detect_wgl_version();
class Dictionary;

Dictionary detect_wgl();

#endif // WINDOWS_ENABLED && GLES3_ENABLED

Expand Down
Loading