diff --git a/drivers/egl/egl_manager.cpp b/drivers/egl/egl_manager.cpp index 10c2119260d0..1473465ced5c 100644 --- a/drivers/egl/egl_manager.cpp +++ b/drivers/egl/egl_manager.cpp @@ -54,12 +54,27 @@ int EGLManager::_get_gldisplay_id(void *p_display) { new_gldisplay.display = p_display; if (GLAD_EGL_VERSION_1_5) { - Vector attribs = _get_platform_display_attributes(); - new_gldisplay.egl_display = eglGetPlatformDisplay(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); + if (explicit_device != EGL_NO_DEVICE_EXT) { + EGLAttrib attribs[] = { + EGL_DEVICE_EXT, + (EGLAttrib)explicit_device, + EGL_NONE, + }; + + print_verbose(vformat("Selected device [0x%x]", (uint64_t)explicit_device)); + + new_gldisplay.egl_display = eglGetPlatformDisplay(_get_platform_extension_enum(), new_gldisplay.display, attribs); + EGLint gpd_err = eglGetError(); + ERR_FAIL_COND_V_MSG(gpd_err != EGL_SUCCESS, -1, vformat("Couldn't get platform display. Error: %x", gpd_err)); + } else { + Vector attribs = _get_platform_display_attributes(); + new_gldisplay.egl_display = eglGetPlatformDisplay(_get_platform_extension_enum(), new_gldisplay.display, (attribs.size() > 0) ? attribs.ptr() : nullptr); + } } else { NativeDisplayType *native_display_type = (NativeDisplayType *)new_gldisplay.display; new_gldisplay.egl_display = eglGetDisplay(*native_display_type); } + ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, -1); ERR_FAIL_COND_V_MSG(new_gldisplay.egl_display == EGL_NO_DISPLAY, -1, "Can't create an EGL display."); @@ -68,6 +83,13 @@ int EGLManager::_get_gldisplay_id(void *p_display) { ERR_FAIL_V_MSG(-1, "Can't initialize an EGL display."); } + EGLDeviceEXT actual_device = EGL_NO_DEVICE_EXT; + if (eglQueryDisplayAttribEXT(new_gldisplay.egl_display, EGL_DEVICE_EXT, (EGLAttrib *)&actual_device)) { + print_verbose(vformat("Display actually uses [0x%x]", (uint64_t)actual_device)); + } + EGLint qda_err = eglGetError(); + ERR_FAIL_COND_V_MSG(qda_err != EGL_SUCCESS, -1, vformat("Couldn't get attribute. Error: %x", qda_err)); + if (!eglBindAPI(_get_platform_api_enum())) { ERR_FAIL_V_MSG(-1, "OpenGL not supported."); } @@ -170,6 +192,8 @@ Error EGLManager::_gldisplay_create_context(GLDisplay &p_gldisplay) { p_gldisplay.egl_context = eglCreateContext(p_gldisplay.egl_display, p_gldisplay.egl_config, EGL_NO_CONTEXT, (context_attribs.size() > 0) ? context_attribs.ptr() : nullptr); ERR_FAIL_COND_V_MSG(p_gldisplay.egl_context == EGL_NO_CONTEXT, ERR_CANT_CREATE, vformat("Can't create an EGL context. Error code: %d", eglGetError())); + eglMakeCurrent(p_gldisplay.egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + return OK; } @@ -182,6 +206,81 @@ Error EGLManager::open_display(void *p_display) { } } +EGLManager::DeviceInfo EGLManager::egl_device_get_info(EGLDeviceEXT p_device) { + DeviceInfo info = {}; + + // We're going to be messing around with current contexts and whatnot. This + // method should be called in a new thread or with a clear context. + ERR_FAIL_COND_V(eglGetCurrentContext() != EGL_NO_CONTEXT, info); + + EGLDisplay eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, p_device, NULL); + if (eglDpy == EGL_NO_DISPLAY) { + print_verbose(vformat("Failed to get EGL display for device %x.\n", p_device)); + return info; + } + + if (!eglInitialize(eglDpy, NULL, NULL)) { + print_verbose(vformat("Failed to initialize EGL for device %x.\n", (uint64_t)p_device)); + return info; + } + + EGLint configAttribs[] = { + EGL_SURFACE_TYPE, + EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, + EGL_OPENGL_BIT, + EGL_NONE, + }; + + EGLConfig eglCfg; + EGLint numConfigs; + if (!eglChooseConfig(eglDpy, configAttribs, &eglCfg, 1, &numConfigs)) { + EGLint eglError = eglGetError(); + print_verbose(vformat("Failed to choose EGL config for device %x. EGL Error: %x\n", (uint64_t)p_device, eglError)); + return info; + } + + if (!eglBindAPI(EGL_OPENGL_API)) { + EGLint eglError = eglGetError(); + print_verbose(vformat("Failed to bind OpenGL API for device %x. EGL Error: %x\n", (uint64_t)p_device, eglError)); + return info; + } + + const EGLint contextAttribs[] = { + EGL_CONTEXT_MAJOR_VERSION, + 3, + EGL_CONTEXT_MINOR_VERSION, + 3, + EGL_NONE, + }; + + EGLContext eglCtx = eglCreateContext(eglDpy, eglCfg, EGL_NO_CONTEXT, contextAttribs); + + if (eglCtx == EGL_NO_CONTEXT) { + EGLint eglError = eglGetError(); + print_verbose(vformat("Failed to create EGL context for device %x. EGL Error: %x\n", (uint64_t)p_device, eglError)); + eglTerminate(eglDpy); + return info; + } + + if (!eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, eglCtx)) { + print_verbose(vformat("Failed to make EGL context current for device %x.\n", (uint64_t)p_device)); + eglDestroyContext(eglDpy, eglCtx); + eglTerminate(eglDpy); + return info; + } + + PFNGLGETSTRINGPROC gl_get_string_proc = (PFNGLGETSTRINGPROC)eglGetProcAddress("glGetString"); + ERR_FAIL_NULL_V_MSG(gl_get_string_proc, info, "OpenGL glGetString method not found."); + info.vendor = (const char *)gl_get_string_proc(GL_VENDOR); + info.renderer = (const char *)gl_get_string_proc(GL_RENDERER); + + eglMakeCurrent(eglDpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); + eglDestroyContext(eglDpy, eglCtx); + eglTerminate(eglDpy); + + return info; +} int EGLManager::display_get_native_visual_id(void *p_display) { int gldisplay_id = _get_gldisplay_id(p_display); ERR_FAIL_COND_V(gldisplay_id < 0, ERR_CANT_CREATE); @@ -398,13 +497,39 @@ Error EGLManager::initialize() { ERR_FAIL_COND_V(eglGetError() != EGL_SUCCESS, ERR_BUG); const char *platform = _get_platform_extension_name(); - if (extensions_string.split(" ").find(platform) < 0) { - ERR_FAIL_V_MSG(ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + bool platform_found = false; + + for (const String &extension : extensions_string.split(" ")) { + if (extension == platform) { + platform_found = true; + } + + if (extension == "EGL_EXT_explicit_device") { + print_verbose("EGL supports explicit device extension, populating device list."); + EGLint num_devices; + + eglQueryDevicesEXT(0, NULL, &num_devices); + ERR_FAIL_COND_V_MSG(eglGetError() != EGL_SUCCESS, FAILED, "Could not get EGL device count."); + + devices.resize(num_devices); + eglQueryDevicesEXT(num_devices, devices.ptrw(), &num_devices); + ERR_FAIL_COND_V_MSG(eglGetError() != EGL_SUCCESS, FAILED, "Could not query EGL devices."); + } } + ERR_FAIL_COND_V_MSG(!platform_found, ERR_UNAVAILABLE, vformat("EGL platform extension \"%s\" not found.", platform)); + return OK; } +Vector EGLManager::get_device_list() const { + return devices; +} + +void EGLManager::set_explicit_device(EGLDeviceEXT p_device) { + explicit_device = p_device; +} + EGLManager::EGLManager() { } diff --git a/drivers/egl/egl_manager.h b/drivers/egl/egl_manager.h index 61d3289b2d62..b640c081bdc0 100644 --- a/drivers/egl/egl_manager.h +++ b/drivers/egl/egl_manager.h @@ -65,6 +65,10 @@ class EGLManager { EGLSurface egl_surface = EGL_NO_SURFACE; }; + Vector devices; + + EGLDeviceEXT explicit_device = EGL_NO_DEVICE_EXT; + LocalVector displays; LocalVector windows; @@ -90,6 +94,14 @@ class EGLManager { Error _gldisplay_create_context(GLDisplay &p_gldisplay); public: + struct DeviceInfo { + String vendor = "Unknown"; + String renderer = "Unknown"; + // TODO: use DRM/SW extensions to add a DeviceType enum. + }; + + DeviceInfo egl_device_get_info(EGLDeviceEXT p_device); + int display_get_native_visual_id(void *p_display); Error open_display(void *p_display); @@ -110,6 +122,9 @@ class EGLManager { Error initialize(); + Vector get_device_list() const; + void set_explicit_device(EGLDeviceEXT p_device); + EGLManager(); virtual ~EGLManager(); }; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 85846335f777..d3fba1f45d60 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -1155,6 +1155,16 @@ String OS_LinuxBSD::get_system_ca_certificates() { return f->get_as_text(); } +#ifdef GLES3_ENABLED +int OS_LinuxBSD::gpu_vendor_get_priority(String vendor) const { + if (gpu_vendor_priority_map.has(vendor)) { + return gpu_vendor_priority_map[vendor]; + } + + return 0; +} +#endif + OS_LinuxBSD::OS_LinuxBSD() { main_loop = nullptr; @@ -1206,6 +1216,16 @@ OS_LinuxBSD::OS_LinuxBSD() { } } #endif // FONTCONFIG_ENABLED + +#ifdef GLES3_ENABLED + gpu_vendor_priority_map["Advanced Micro Devices, Inc."] = 30; + gpu_vendor_priority_map["AMD"] = 30; + gpu_vendor_priority_map["NVIDIA Corporation"] = 30; + gpu_vendor_priority_map["X.Org"] = 30; + gpu_vendor_priority_map["Intel Open Source Technology Center"] = 20; + gpu_vendor_priority_map["Intel"] = 20; + gpu_vendor_priority_map["nouveau"] = 10; +#endif } OS_LinuxBSD::~OS_LinuxBSD() { diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 9084061eb96c..02424675872a 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -77,6 +77,10 @@ class OS_LinuxBSD : public OS_Unix { AudioDriverPulseAudio driver_pulseaudio; #endif +#ifdef GLES3_ENABLED + HashMap gpu_vendor_priority_map; +#endif + CrashHandler crash_handler; MainLoop *main_loop = nullptr; @@ -138,6 +142,10 @@ class OS_LinuxBSD : public OS_Unix { virtual String get_system_ca_certificates() override; +#ifdef GLES3_ENABLED + int gpu_vendor_get_priority(String vendor) const; +#endif + OS_LinuxBSD(); ~OS_LinuxBSD(); }; diff --git a/platform/linuxbsd/wayland/SCsub b/platform/linuxbsd/wayland/SCsub index cab45b76723a..ba32eac246b2 100644 --- a/platform/linuxbsd/wayland/SCsub +++ b/platform/linuxbsd/wayland/SCsub @@ -178,7 +178,6 @@ source_files = [ "display_server_wayland.cpp", "wayland_thread.cpp", "key_mapping_xkb.cpp", - "detect_prime_egl.cpp", ] if env["use_sowrap"]: diff --git a/platform/linuxbsd/wayland/detect_prime_egl.cpp b/platform/linuxbsd/wayland/detect_prime_egl.cpp deleted file mode 100644 index 4bee32ae3ad4..000000000000 --- a/platform/linuxbsd/wayland/detect_prime_egl.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************/ -/* detect_prime_egl.cpp */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -#ifdef GLES3_ENABLED -#ifdef EGL_ENABLED - -#include "detect_prime_egl.h" - -#include "core/string/print_string.h" -#include "core/string/ustring.h" - -#include - -#ifdef GLAD_ENABLED -#include "thirdparty/glad/glad/egl.h" -#include "thirdparty/glad/glad/gl.h" -#else -#include -#include -#include -#endif // GLAD_ENABLED - -#include - -#include -#include -#include - -// To prevent shadowing warnings. -#undef glGetString - -// Runs inside a child. Exiting will not quit the engine. -void DetectPrimeEGL::create_context() { -#if defined(GLAD_ENABLED) - if (!gladLoaderLoadEGL(nullptr)) { - print_verbose("Unable to load EGL, GPU detection skipped."); - quick_exit(1); - } -#endif - - EGLDisplay egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - EGLConfig egl_config; - EGLContext egl_context = EGL_NO_CONTEXT; - - eglInitialize(egl_display, NULL, NULL); - -#if defined(GLAD_ENABLED) - if (!gladLoaderLoadEGL(egl_display)) { - print_verbose("Unable to load EGL, GPU detection skipped."); - quick_exit(1); - } -#endif - - eglBindAPI(EGL_OPENGL_API); - - EGLint attribs[] = { - EGL_RED_SIZE, - 1, - EGL_BLUE_SIZE, - 1, - EGL_GREEN_SIZE, - 1, - EGL_DEPTH_SIZE, - 24, - EGL_NONE, - }; - - EGLint config_count = 0; - eglChooseConfig(egl_display, attribs, &egl_config, 1, &config_count); - - EGLint context_attribs[] = { - EGL_CONTEXT_MAJOR_VERSION, 3, - EGL_CONTEXT_MINOR_VERSION, 3, - EGL_NONE - }; - - egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attribs); - if (egl_context == EGL_NO_CONTEXT) { - print_verbose("Unable to create an EGL context, GPU detection skipped."); - quick_exit(1); - } - - eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context); -} - -int DetectPrimeEGL::detect_prime() { - pid_t p; - int priorities[4] = {}; - String vendors[4]; - String renderers[4]; - - for (int i = 0; i < 4; ++i) { - vendors[i] = "Unknown"; - renderers[i] = "Unknown"; - } - - for (int i = 0; i < 4; ++i) { - int fdset[2]; - - if (pipe(fdset) == -1) { - print_verbose("Failed to pipe(), using default GPU"); - return 0; - } - - // Fork so the driver initialization can crash without taking down the engine. - p = fork(); - - if (p > 0) { - // Main thread - - int stat_loc = 0; - char string[201]; - string[200] = '\0'; - - close(fdset[1]); - - waitpid(p, &stat_loc, 0); - - if (!stat_loc) { - // No need to do anything complicated here. Anything less than - // PIPE_BUF will be delivered in one read() call. - // Leave it 'Unknown' otherwise. - if (read(fdset[0], string, sizeof(string) - 1) > 0) { - vendors[i] = string; - renderers[i] = string + strlen(string) + 1; - } - } - - close(fdset[0]); - } else { - // In child, exit() here will not quit the engine. - - // Prevent false leak reports as we will not be properly - // cleaning up these processes, and fork() makes a copy - // of all globals. - CoreGlobals::leak_reporting_enabled = false; - - char string[201]; - - close(fdset[0]); - - setenv("DRI_PRIME", itos(i).utf8().ptr(), 1); - - create_context(); - - PFNGLGETSTRINGPROC glGetString = (PFNGLGETSTRINGPROC)eglGetProcAddress("glGetString"); - const char *vendor = (const char *)glGetString(GL_VENDOR); - const char *renderer = (const char *)glGetString(GL_RENDERER); - - unsigned int vendor_len = strlen(vendor) + 1; - unsigned int renderer_len = strlen(renderer) + 1; - - if (vendor_len + renderer_len >= sizeof(string)) { - renderer_len = 200 - vendor_len; - } - - memcpy(&string, vendor, vendor_len); - memcpy(&string[vendor_len], renderer, renderer_len); - - if (write(fdset[1], string, vendor_len + renderer_len) == -1) { - print_verbose("Couldn't write vendor/renderer string."); - } - close(fdset[1]); - - // The function quick_exit() is used because exit() will call destructors on static objects copied by fork(). - // These objects will be freed anyway when the process finishes execution. - quick_exit(0); - } - } - - int preferred = 0; - int priority = 0; - - if (vendors[0] == vendors[1]) { - print_verbose("Only one GPU found, using default."); - return 0; - } - - for (int i = 3; i >= 0; --i) { - const Vendor *v = vendor_map; - while (v->glxvendor) { - if (v->glxvendor == vendors[i]) { - priorities[i] = v->priority; - - if (v->priority >= priority) { - priority = v->priority; - preferred = i; - } - } - ++v; - } - } - - print_verbose("Found renderers:"); - for (int i = 0; i < 4; ++i) { - print_verbose("Renderer " + itos(i) + ": " + renderers[i] + " with priority: " + itos(priorities[i])); - } - - print_verbose("Using renderer: " + renderers[preferred]); - return preferred; -} - -#endif // EGL_ENABLED -#endif // GLES3_ENABLED diff --git a/platform/linuxbsd/wayland/detect_prime_egl.h b/platform/linuxbsd/wayland/detect_prime_egl.h deleted file mode 100644 index 26351b0dce2c..000000000000 --- a/platform/linuxbsd/wayland/detect_prime_egl.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************/ -/* detect_prime_egl.h */ -/**************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/**************************************************************************/ -/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ -/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/**************************************************************************/ - -#ifndef DETECT_PRIME_EGL_H -#define DETECT_PRIME_EGL_H - -#ifdef GLES3_ENABLED -#ifdef EGL_ENABLED - -class DetectPrimeEGL { -private: - struct Vendor { - const char *glxvendor = nullptr; - int priority = 0; - }; - - static constexpr Vendor vendor_map[] = { - { "Advanced Micro Devices, Inc.", 30 }, - { "AMD", 30 }, - { "NVIDIA Corporation", 30 }, - { "X.Org", 30 }, - { "Intel Open Source Technology Center", 20 }, - { "Intel", 20 }, - { "nouveau", 10 }, - { "Mesa Project", 0 }, - { nullptr, 0 } - }; - - static void create_context(); - -public: - static int detect_prime(); -}; - -#endif // GLES3_ENABLED -#endif // EGL_ENABLED - -#endif // DETECT_PRIME_EGL_H diff --git a/platform/linuxbsd/wayland/display_server_wayland.cpp b/platform/linuxbsd/wayland/display_server_wayland.cpp index c957dea32d42..806a1d639ad6 100644 --- a/platform/linuxbsd/wayland/display_server_wayland.cpp +++ b/platform/linuxbsd/wayland/display_server_wayland.cpp @@ -39,12 +39,13 @@ #define DEBUG_LOG_WAYLAND(...) #endif +#include "os_linuxbsd.h" + #ifdef VULKAN_ENABLED #include "servers/rendering/renderer_rd/renderer_compositor_rd.h" #endif #ifdef GLES3_ENABLED -#include "detect_prime_egl.h" #include "drivers/gles3/rasterizer_gles3.h" #endif @@ -1285,48 +1286,6 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win #ifdef GLES3_ENABLED if (p_rendering_driver == "opengl3") { - if (getenv("DRI_PRIME") == nullptr) { - int prime_idx = -1; - - if (getenv("PRIMUS_DISPLAY") || - getenv("PRIMUS_libGLd") || - getenv("PRIMUS_libGLa") || - getenv("PRIMUS_libGL") || - getenv("PRIMUS_LOAD_GLOBAL") || - getenv("BUMBLEBEE_SOCKET") || - getenv("__NV_PRIME_RENDER_OFFLOAD")) { - print_verbose("Optirun/primusrun detected. Skipping GPU detection"); - prime_idx = 0; - } - - // Some tools use fake libGL libraries and have them override the real one using - // LD_LIBRARY_PATH, so we skip them. *But* Steam also sets LD_LIBRARY_PATH for its - // runtime and includes system `/lib` and `/lib64`... so ignore Steam. - if (prime_idx == -1 && getenv("LD_LIBRARY_PATH") && !getenv("STEAM_RUNTIME_LIBRARY_PATH")) { - String ld_library_path(getenv("LD_LIBRARY_PATH")); - Vector libraries = ld_library_path.split(":"); - - for (int i = 0; i < libraries.size(); ++i) { - if (FileAccess::exists(libraries[i] + "/libGL.so.1") || - FileAccess::exists(libraries[i] + "/libGL.so")) { - print_verbose("Custom libGL override detected. Skipping GPU detection"); - prime_idx = 0; - } - } - } - - if (prime_idx == -1) { - print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); - prime_idx = DetectPrimeEGL::detect_prime(); - } - - if (prime_idx) { - print_line(vformat("Found discrete GPU, setting DRI_PRIME=%d to use it.", prime_idx)); - print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); - setenv("DRI_PRIME", itos(prime_idx).utf8().ptr(), 1); - } - } - egl_manager = memnew(EGLManagerWayland); #ifdef SOWRAP_ENABLED @@ -1343,6 +1302,33 @@ DisplayServerWayland::DisplayServerWayland(const String &p_rendering_driver, Win ERR_FAIL_MSG("Could not initialize GLES3."); } + Vector devices = egl_manager->get_device_list(); + + // TODO: gpu-index check. + if (!devices.is_empty()) { + print_verbose("Auto-detecting GPUs."); + } + + int best_priority = -1; + EGLDeviceEXT best_device = EGL_NO_DEVICE_EXT; + + for (EGLDeviceEXT &device : devices) { + EGLManager::DeviceInfo info = egl_manager->egl_device_get_info(device); + int priority = ((OS_LinuxBSD *)OS::get_singleton())->gpu_vendor_get_priority(info.vendor); + + print_verbose(vformat("Found device [0x%x] %s - %s with priority %d.", (uint64_t)device, info.vendor, info.renderer, priority)); + + if (priority > best_priority) { + best_priority = priority; + best_device = device; + } + } + + if (best_device != EGL_NO_DEVICE_EXT) { + print_verbose(vformat("Selected device [0x%x]", (uint64_t)best_device)); + egl_manager->set_explicit_device(best_device); + } + RasterizerGLES3::make_current(true); } #endif // GLES3_ENABLED diff --git a/thirdparty/glad/EGL/eglplatform.h b/thirdparty/glad/EGL/eglplatform.h index 99362a23deea..6786afd90b68 100644 --- a/thirdparty/glad/EGL/eglplatform.h +++ b/thirdparty/glad/EGL/eglplatform.h @@ -64,6 +64,12 @@ typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; typedef HWND EGLNativeWindowType; +#elif defined(__QNX__) + +typedef khronos_uintptr_t EGLNativeDisplayType; +typedef struct _screen_pixmap* EGLNativePixmapType; /* screen_pixmap_t */ +typedef struct _screen_window* EGLNativeWindowType; /* screen_window_t */ + #elif defined(__EMSCRIPTEN__) typedef int EGLNativeDisplayType; diff --git a/thirdparty/glad/egl.c b/thirdparty/glad/egl.c index e120ea6b2cd8..4f8a70f0aba6 100644 --- a/thirdparty/glad/egl.c +++ b/thirdparty/glad/egl.c @@ -30,6 +30,13 @@ int GLAD_EGL_VERSION_1_3 = 0; int GLAD_EGL_VERSION_1_4 = 0; int GLAD_EGL_VERSION_1_5 = 0; int GLAD_EGL_ANDROID_blob_cache = 0; +int GLAD_EGL_EXT_client_extensions = 0; +int GLAD_EGL_EXT_device_base = 0; +int GLAD_EGL_EXT_device_enumeration = 0; +int GLAD_EGL_EXT_device_query = 0; +int GLAD_EGL_EXT_explicit_device = 0; +int GLAD_EGL_EXT_platform_base = 0; +int GLAD_EGL_EXT_platform_device = 0; int GLAD_EGL_KHR_platform_wayland = 0; int GLAD_EGL_KHR_platform_x11 = 0; @@ -46,7 +53,9 @@ PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer = PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface = NULL; PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface = NULL; PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface = NULL; +PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT = NULL; PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface = NULL; +PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT = NULL; PFNEGLCREATESYNCPROC glad_eglCreateSync = NULL; PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface = NULL; PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext = NULL; @@ -61,12 +70,17 @@ PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface = NULL; PFNEGLGETDISPLAYPROC glad_eglGetDisplay = NULL; PFNEGLGETERRORPROC glad_eglGetError = NULL; PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay = NULL; +PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT = NULL; PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress = NULL; PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib = NULL; PFNEGLINITIALIZEPROC glad_eglInitialize = NULL; PFNEGLMAKECURRENTPROC glad_eglMakeCurrent = NULL; PFNEGLQUERYAPIPROC glad_eglQueryAPI = NULL; PFNEGLQUERYCONTEXTPROC glad_eglQueryContext = NULL; +PFNEGLQUERYDEVICEATTRIBEXTPROC glad_eglQueryDeviceAttribEXT = NULL; +PFNEGLQUERYDEVICESTRINGEXTPROC glad_eglQueryDeviceStringEXT = NULL; +PFNEGLQUERYDEVICESEXTPROC glad_eglQueryDevicesEXT = NULL; +PFNEGLQUERYDISPLAYATTRIBEXTPROC glad_eglQueryDisplayAttribEXT = NULL; PFNEGLQUERYSTRINGPROC glad_eglQueryString = NULL; PFNEGLQUERYSURFACEPROC glad_eglQuerySurface = NULL; PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage = NULL; @@ -145,6 +159,29 @@ static void glad_egl_load_EGL_ANDROID_blob_cache( GLADuserptrloadfunc load, void if(!GLAD_EGL_ANDROID_blob_cache) return; glad_eglSetBlobCacheFuncsANDROID = (PFNEGLSETBLOBCACHEFUNCSANDROIDPROC) load(userptr, "eglSetBlobCacheFuncsANDROID"); } +static void glad_egl_load_EGL_EXT_device_base( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_device_base) return; + glad_eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC) load(userptr, "eglQueryDeviceAttribEXT"); + glad_eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC) load(userptr, "eglQueryDeviceStringEXT"); + glad_eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) load(userptr, "eglQueryDevicesEXT"); + glad_eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC) load(userptr, "eglQueryDisplayAttribEXT"); +} +static void glad_egl_load_EGL_EXT_device_enumeration( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_device_enumeration) return; + glad_eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) load(userptr, "eglQueryDevicesEXT"); +} +static void glad_egl_load_EGL_EXT_device_query( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_device_query) return; + glad_eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC) load(userptr, "eglQueryDeviceAttribEXT"); + glad_eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC) load(userptr, "eglQueryDeviceStringEXT"); + glad_eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC) load(userptr, "eglQueryDisplayAttribEXT"); +} +static void glad_egl_load_EGL_EXT_platform_base( GLADuserptrloadfunc load, void* userptr) { + if(!GLAD_EGL_EXT_platform_base) return; + glad_eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) load(userptr, "eglCreatePlatformPixmapSurfaceEXT"); + glad_eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) load(userptr, "eglCreatePlatformWindowSurfaceEXT"); + glad_eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) load(userptr, "eglGetPlatformDisplayEXT"); +} @@ -183,6 +220,13 @@ static int glad_egl_find_extensions_egl(EGLDisplay display) { if (!glad_egl_get_extensions(display, &extensions)) return 0; GLAD_EGL_ANDROID_blob_cache = glad_egl_has_extension(extensions, "EGL_ANDROID_blob_cache"); + GLAD_EGL_EXT_client_extensions = glad_egl_has_extension(extensions, "EGL_EXT_client_extensions"); + GLAD_EGL_EXT_device_base = glad_egl_has_extension(extensions, "EGL_EXT_device_base"); + GLAD_EGL_EXT_device_enumeration = glad_egl_has_extension(extensions, "EGL_EXT_device_enumeration"); + GLAD_EGL_EXT_device_query = glad_egl_has_extension(extensions, "EGL_EXT_device_query"); + GLAD_EGL_EXT_explicit_device = glad_egl_has_extension(extensions, "EGL_EXT_explicit_device"); + GLAD_EGL_EXT_platform_base = glad_egl_has_extension(extensions, "EGL_EXT_platform_base"); + GLAD_EGL_EXT_platform_device = glad_egl_has_extension(extensions, "EGL_EXT_platform_device"); GLAD_EGL_KHR_platform_wayland = glad_egl_has_extension(extensions, "EGL_KHR_platform_wayland"); GLAD_EGL_KHR_platform_x11 = glad_egl_has_extension(extensions, "EGL_KHR_platform_x11"); @@ -248,6 +292,10 @@ int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userp if (!glad_egl_find_extensions_egl(display)) return 0; glad_egl_load_EGL_ANDROID_blob_cache(load, userptr); + glad_egl_load_EGL_EXT_device_base(load, userptr); + glad_egl_load_EGL_EXT_device_enumeration(load, userptr); + glad_egl_load_EGL_EXT_device_query(load, userptr); + glad_egl_load_EGL_EXT_platform_base(load, userptr); return version; diff --git a/thirdparty/glad/glad/egl.h b/thirdparty/glad/glad/egl.h index 1bf35c1404a5..79e22e145b43 100644 --- a/thirdparty/glad/glad/egl.h +++ b/thirdparty/glad/glad/egl.h @@ -1,11 +1,11 @@ /** - * Loader generated by glad 2.0.3 on Fri Feb 3 07:06:48 2023 + * Loader generated by glad 2.0.5 on Fri Feb 9 12:27:47 2024 * * SPDX-License-Identifier: (WTFPL OR CC0-1.0) AND Apache-2.0 * * Generator: C/C++ * Specification: egl - * Extensions: 3 + * Extensions: 10 * * APIs: * - egl=1.5 @@ -19,10 +19,10 @@ * - ON_DEMAND = False * * Commandline: - * --api='egl=1.5' --extensions='EGL_ANDROID_blob_cache,EGL_KHR_platform_wayland,EGL_KHR_platform_x11' c --loader + * --api='egl=1.5' --extensions='EGL_ANDROID_blob_cache,EGL_EXT_client_extensions,EGL_EXT_device_base,EGL_EXT_device_enumeration,EGL_EXT_device_query,EGL_EXT_explicit_device,EGL_EXT_platform_base,EGL_EXT_platform_device,EGL_KHR_platform_wayland,EGL_KHR_platform_x11' c --loader * * Online: - * http://glad.sh/#api=egl%3D1.5&extensions=EGL_ANDROID_blob_cache%2CEGL_KHR_platform_wayland%2CEGL_KHR_platform_x11&generator=c&options=LOADER + * http://glad.sh/#api=egl%3D1.5&extensions=EGL_ANDROID_blob_cache%2CEGL_EXT_client_extensions%2CEGL_EXT_device_base%2CEGL_EXT_device_enumeration%2CEGL_EXT_device_query%2CEGL_EXT_explicit_device%2CEGL_EXT_platform_base%2CEGL_EXT_platform_device%2CEGL_KHR_platform_wayland%2CEGL_KHR_platform_x11&generator=c&options=LOADER * */ @@ -141,7 +141,7 @@ extern "C" { #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -#define GLAD_GENERATOR_VERSION "2.0.3" +#define GLAD_GENERATOR_VERSION "2.0.5" typedef void (*GLADapiproc)(void); @@ -165,6 +165,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_BAD_CONFIG 0x3005 #define EGL_BAD_CONTEXT 0x3006 #define EGL_BAD_CURRENT_SURFACE 0x3007 +#define EGL_BAD_DEVICE_EXT 0x322B #define EGL_BAD_DISPLAY 0x3008 #define EGL_BAD_MATCH 0x3009 #define EGL_BAD_NATIVE_PIXMAP 0x300A @@ -202,6 +203,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_CORE_NATIVE_ENGINE 0x305B #define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) #define EGL_DEPTH_SIZE 0x3025 +#define EGL_DEVICE_EXT 0x322C #define EGL_DISPLAY_SCALING 10000 #define EGL_DONT_CARE EGL_CAST(EGLint,-1) #define EGL_DRAW 0x3059 @@ -250,6 +252,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_NON_CONFORMANT_CONFIG 0x3051 #define EGL_NOT_INITIALIZED 0x3001 #define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) #define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) #define EGL_NO_IMAGE EGL_CAST(EGLImage,0) #define EGL_NO_RESET_NOTIFICATION 0x31BE @@ -268,6 +271,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_PBUFFER_BIT 0x0001 #define EGL_PIXEL_ASPECT_RATIO 0x3092 #define EGL_PIXMAP_BIT 0x0002 +#define EGL_PLATFORM_DEVICE_EXT 0x313F #define EGL_PLATFORM_WAYLAND_KHR 0x31D8 #define EGL_PLATFORM_X11_KHR 0x31D5 #define EGL_PLATFORM_X11_SCREEN_KHR 0x31D6 @@ -399,6 +403,20 @@ GLAD_API_CALL int GLAD_EGL_VERSION_1_4; GLAD_API_CALL int GLAD_EGL_VERSION_1_5; #define EGL_ANDROID_blob_cache 1 GLAD_API_CALL int GLAD_EGL_ANDROID_blob_cache; +#define EGL_EXT_client_extensions 1 +GLAD_API_CALL int GLAD_EGL_EXT_client_extensions; +#define EGL_EXT_device_base 1 +GLAD_API_CALL int GLAD_EGL_EXT_device_base; +#define EGL_EXT_device_enumeration 1 +GLAD_API_CALL int GLAD_EGL_EXT_device_enumeration; +#define EGL_EXT_device_query 1 +GLAD_API_CALL int GLAD_EGL_EXT_device_query; +#define EGL_EXT_explicit_device 1 +GLAD_API_CALL int GLAD_EGL_EXT_explicit_device; +#define EGL_EXT_platform_base 1 +GLAD_API_CALL int GLAD_EGL_EXT_platform_base; +#define EGL_EXT_platform_device 1 +GLAD_API_CALL int GLAD_EGL_EXT_platform_device; #define EGL_KHR_platform_wayland 1 GLAD_API_CALL int GLAD_EGL_KHR_platform_wayland; #define EGL_KHR_platform_x11 1 @@ -416,7 +434,9 @@ typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDi typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); +typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list); typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx); @@ -431,12 +451,17 @@ typedef EGLSurface (GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw); typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id); typedef EGLint (GLAD_API_PTR *PFNEGLGETERRORPROC)(void); typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void * native_display, const EGLAttrib * attrib_list); +typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void * native_display, const EGLint * attrib_list); typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char * procname); typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); typedef EGLBoolean (GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint * major, EGLint * minor); typedef EGLBoolean (GLAD_API_PTR *PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); typedef EGLenum (GLAD_API_PTR *PFNEGLQUERYAPIPROC)(void); typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDEVICEATTRIBEXTPROC)(EGLDeviceEXT device, EGLint attribute, EGLAttrib * value); +typedef const char * (GLAD_API_PTR *PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT device, EGLint name); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDEVICESEXTPROC)(EGLint max_devices, EGLDeviceEXT * devices, EGLint * num_devices); +typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDISPLAYATTRIBEXTPROC)(EGLDisplay dpy, EGLint attribute, EGLAttrib * value); typedef const char * (GLAD_API_PTR *PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name); typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value); typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); @@ -473,8 +498,12 @@ GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface; #define eglCreatePixmapSurface glad_eglCreatePixmapSurface GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface; #define eglCreatePlatformPixmapSurface glad_eglCreatePlatformPixmapSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT; +#define eglCreatePlatformPixmapSurfaceEXT glad_eglCreatePlatformPixmapSurfaceEXT GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; #define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface +GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT; +#define eglCreatePlatformWindowSurfaceEXT glad_eglCreatePlatformWindowSurfaceEXT GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; #define eglCreateSync glad_eglCreateSync GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface; @@ -503,6 +532,8 @@ GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError; #define eglGetError glad_eglGetError GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay; #define eglGetPlatformDisplay glad_eglGetPlatformDisplay +GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT; +#define eglGetPlatformDisplayEXT glad_eglGetPlatformDisplayEXT GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; #define eglGetProcAddress glad_eglGetProcAddress GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; @@ -515,6 +546,14 @@ GLAD_API_CALL PFNEGLQUERYAPIPROC glad_eglQueryAPI; #define eglQueryAPI glad_eglQueryAPI GLAD_API_CALL PFNEGLQUERYCONTEXTPROC glad_eglQueryContext; #define eglQueryContext glad_eglQueryContext +GLAD_API_CALL PFNEGLQUERYDEVICEATTRIBEXTPROC glad_eglQueryDeviceAttribEXT; +#define eglQueryDeviceAttribEXT glad_eglQueryDeviceAttribEXT +GLAD_API_CALL PFNEGLQUERYDEVICESTRINGEXTPROC glad_eglQueryDeviceStringEXT; +#define eglQueryDeviceStringEXT glad_eglQueryDeviceStringEXT +GLAD_API_CALL PFNEGLQUERYDEVICESEXTPROC glad_eglQueryDevicesEXT; +#define eglQueryDevicesEXT glad_eglQueryDevicesEXT +GLAD_API_CALL PFNEGLQUERYDISPLAYATTRIBEXTPROC glad_eglQueryDisplayAttribEXT; +#define eglQueryDisplayAttribEXT glad_eglQueryDisplayAttribEXT GLAD_API_CALL PFNEGLQUERYSTRINGPROC glad_eglQueryString; #define eglQueryString glad_eglQueryString GLAD_API_CALL PFNEGLQUERYSURFACEPROC glad_eglQuerySurface;