[ANGLE] Add fallback control options and defaults.
[macOS] Use ANGLE by default if engine is built with statically linked ANGLE. [Windows] Add option enable/disable fallback to ANGLE and option force specific GPU to always use ANGLE.
This commit is contained in:
parent
a2f90d565a
commit
ac3fc2a8a1
|
@ -2366,6 +2366,13 @@
|
||||||
<member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default=""opengl3"">
|
<member name="rendering/gl_compatibility/driver.windows" type="String" setter="" getter="" default=""opengl3"">
|
||||||
Windows override for [member rendering/gl_compatibility/driver].
|
Windows override for [member rendering/gl_compatibility/driver].
|
||||||
</member>
|
</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">
|
<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.
|
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>
|
</member>
|
||||||
|
|
|
@ -1752,6 +1752,10 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
String default_driver = driver_hints.get_slice(",", 0);
|
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("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.windows", PROPERTY_HINT_ENUM, driver_hints_angle), default_driver);
|
||||||
|
@ -1759,8 +1763,11 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
||||||
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.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.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.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/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.
|
// Start with RenderingDevice-based backends. Should be included if any RD driver present.
|
||||||
|
|
|
@ -4579,9 +4579,22 @@ DisplayServerWindows::DisplayServerWindows(const String &p_rendering_driver, Win
|
||||||
// Init context and rendering device
|
// Init context and rendering device
|
||||||
#if defined(GLES3_ENABLED)
|
#if defined(GLES3_ENABLED)
|
||||||
|
|
||||||
if (rendering_driver == "opengl3") {
|
bool fallback = GLOBAL_GET("rendering/gl_compatibility/fallback_to_angle");
|
||||||
int gl_version = detect_wgl_version();
|
if (fallback && (rendering_driver == "opengl3")) {
|
||||||
if (gl_version < 30003) {
|
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.");
|
WARN_PRINT("Your video card drivers seem not to support the required OpenGL 3.3 version, switching to ANGLE.");
|
||||||
rendering_driver = "opengl3_angle";
|
rendering_driver = "opengl3_angle";
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
#include "core/string/print_string.h"
|
#include "core/string/print_string.h"
|
||||||
#include "core/string/ustring.h"
|
#include "core/string/ustring.h"
|
||||||
|
#include "core/variant/dictionary.h"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
|
||||||
|
@ -64,9 +65,11 @@ typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int
|
||||||
typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
|
typedef void *(APIENTRY *PFNWGLGETPROCADDRESS)(LPCSTR);
|
||||||
typedef const char *(APIENTRY *PFNWGLGETSTRINGPROC)(unsigned int);
|
typedef const char *(APIENTRY *PFNWGLGETSTRINGPROC)(unsigned int);
|
||||||
|
|
||||||
int detect_wgl_version() {
|
Dictionary detect_wgl() {
|
||||||
int major = 0;
|
Dictionary gl_info;
|
||||||
int minor = 0;
|
gl_info["version"] = 0;
|
||||||
|
gl_info["vendor"] = String();
|
||||||
|
gl_info["name"] = String();
|
||||||
|
|
||||||
PFNWGLCREATECONTEXT gd_wglCreateContext;
|
PFNWGLCREATECONTEXT gd_wglCreateContext;
|
||||||
PFNWGLMAKECURRENT gd_wglMakeCurrent;
|
PFNWGLMAKECURRENT gd_wglMakeCurrent;
|
||||||
|
@ -75,14 +78,14 @@ int detect_wgl_version() {
|
||||||
|
|
||||||
HMODULE module = LoadLibraryW(L"opengl32.dll");
|
HMODULE module = LoadLibraryW(L"opengl32.dll");
|
||||||
if (!module) {
|
if (!module) {
|
||||||
return 0;
|
return gl_info;
|
||||||
}
|
}
|
||||||
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
|
gd_wglCreateContext = (PFNWGLCREATECONTEXT)GetProcAddress(module, "wglCreateContext");
|
||||||
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
|
gd_wglMakeCurrent = (PFNWGLMAKECURRENT)GetProcAddress(module, "wglMakeCurrent");
|
||||||
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
|
gd_wglDeleteContext = (PFNWGLDELETECONTEXT)GetProcAddress(module, "wglDeleteContext");
|
||||||
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
|
gd_wglGetProcAddress = (PFNWGLGETPROCADDRESS)GetProcAddress(module, "wglGetProcAddress");
|
||||||
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
|
if (!gd_wglCreateContext || !gd_wglMakeCurrent || !gd_wglDeleteContext || !gd_wglGetProcAddress) {
|
||||||
return 0;
|
return gl_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPCWSTR class_name = L"EngineWGLDetect";
|
LPCWSTR class_name = L"EngineWGLDetect";
|
||||||
|
@ -151,8 +154,8 @@ int detect_wgl_version() {
|
||||||
};
|
};
|
||||||
const char *version = (const char *)gd_wglGetString(WGL_VERSION);
|
const char *version = (const char *)gd_wglGetString(WGL_VERSION);
|
||||||
if (version) {
|
if (version) {
|
||||||
const String device_vendor = String::utf8((const char *)gd_wglGetString(WGL_VENDOR)).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();
|
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++) {
|
for (int i = 0; prefixes[i]; i++) {
|
||||||
size_t length = strlen(prefixes[i]);
|
size_t length = strlen(prefixes[i]);
|
||||||
if (strncmp(version, prefixes[i], length) == 0) {
|
if (strncmp(version, prefixes[i], length) == 0) {
|
||||||
|
@ -160,12 +163,17 @@ int detect_wgl_version() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
int major = 0;
|
||||||
|
int minor = 0;
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
sscanf_s(version, "%d.%d", &major, &minor);
|
sscanf_s(version, "%d.%d", &major, &minor);
|
||||||
#else
|
#else
|
||||||
sscanf(version, "%d.%d", &major, &minor);
|
sscanf(version, "%d.%d", &major, &minor);
|
||||||
#endif
|
#endif
|
||||||
print_verbose(vformat("Native OpenGL API detected: %d.%d: %s - %s", major, minor, device_vendor, device_name));
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -183,7 +191,7 @@ int detect_wgl_version() {
|
||||||
}
|
}
|
||||||
UnregisterClassW(class_name, hInstance);
|
UnregisterClassW(class_name, hInstance);
|
||||||
|
|
||||||
return major * 10000 + minor;
|
return gl_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // WINDOWS_ENABLED && GLES3_ENABLED
|
#endif // WINDOWS_ENABLED && GLES3_ENABLED
|
||||||
|
|
|
@ -33,7 +33,9 @@
|
||||||
|
|
||||||
#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
|
#if defined(WINDOWS_ENABLED) && defined(GLES3_ENABLED)
|
||||||
|
|
||||||
int detect_wgl_version();
|
class Dictionary;
|
||||||
|
|
||||||
|
Dictionary detect_wgl();
|
||||||
|
|
||||||
#endif // WINDOWS_ENABLED && GLES3_ENABLED
|
#endif // WINDOWS_ENABLED && GLES3_ENABLED
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue