diff --git a/src/patches/0005-Made-GLES-work-on-X11.patch b/src/patches/0005-Made-GLES-work-on-X11.patch index 4960967..6d5f52a 100644 --- a/src/patches/0005-Made-GLES-work-on-X11.patch +++ b/src/patches/0005-Made-GLES-work-on-X11.patch @@ -1,4 +1,4 @@ -From d1611b3578c0344a9b08d4981e1357560869ff1f Mon Sep 17 00:00:00 2001 +From d4ef511a569ee071a98924a3e7314cc2cd06ec50 Mon Sep 17 00:00:00 2001 From: Sergey Lapin Date: Thu, 20 Mar 2025 21:49:14 +0300 Subject: [PATCH] Made GLES work on X11 @@ -6,7 +6,7 @@ Subject: [PATCH] Made GLES work on X11 --- core/SCsub | 2 +- .../gles2/rasterizer_canvas_base_gles2.cpp | 3 + - drivers/gles2/rasterizer_gles2.cpp | 10 + + drivers/gles2/rasterizer_gles2.cpp | 13 + drivers/gles2/rasterizer_storage_gles2.cpp | 6 + drivers/gles2/shader_gles2.cpp | 6 +- modules/denoise/config.py | 2 +- @@ -17,12 +17,12 @@ Subject: [PATCH] Made GLES work on X11 modules/webm/config.py | 2 +- modules/webm/libvpx/SCsub | 4 +- platform/x11es/SCsub | 27 + - platform/x11es/context_gl_x11.cpp | 306 ++ - platform/x11es/context_gl_x11.h | 89 + + platform/x11es/context_gl_x11.cpp | 480 ++ + platform/x11es/context_gl_x11.h | 101 + platform/x11es/crash_handler_x11.cpp | 173 + platform/x11es/crash_handler_x11.h | 47 + platform/x11es/detect.py | 433 ++ - platform/x11es/detect_prime.cpp | 246 + + platform/x11es/detect_prime.cpp | 315 ++ platform/x11es/detect_prime.h | 38 + platform/x11es/godot_x11.cpp | 83 + platform/x11es/joypad_linux.cpp | 595 +++ @@ -32,13 +32,13 @@ Subject: [PATCH] Made GLES work on X11 platform/x11es/libudev-so_wrap.c | 829 +++ platform/x11es/libudev-so_wrap.h | 376 ++ platform/x11es/logo.png | Bin 0 -> 1679 bytes - platform/x11es/os_x11.cpp | 4493 +++++++++++++++++ + platform/x11es/os_x11.cpp | 4497 +++++++++++++++++ platform/x11es/os_x11.h | 398 ++ platform/x11es/platform_config.h | 49 + platform/x11es/platform_x11_builders.py | 18 + platform/x11es/power_x11.cpp | 571 +++ platform/x11es/power_x11.h | 65 + - 34 files changed, 11006 insertions(+), 11 deletions(-) + 34 files changed, 11268 insertions(+), 11 deletions(-) create mode 100644 platform/x11es/SCsub create mode 100644 platform/x11es/context_gl_x11.cpp create mode 100644 platform/x11es/context_gl_x11.h @@ -90,24 +90,27 @@ index 8615dc2e64..3abf65732b 100644 #endif diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp -index c8eb0c7509..cbd11af2de 100644 +index c8eb0c7509..4f03728350 100644 --- a/drivers/gles2/rasterizer_gles2.cpp +++ b/drivers/gles2/rasterizer_gles2.cpp -@@ -79,6 +79,9 @@ +@@ -79,6 +79,12 @@ #include #include #endif ++#define EGL ++#ifndef EGL +#if !defined(OPENGL_ENABLED) && defined(X11_ENABLED) +#include ++#endif +#endif #if defined(MINGW_ENABLED) || defined(_MSC_VER) #define strcpy strcpy_s -@@ -246,10 +249,17 @@ void RasterizerGLES2::initialize() { +@@ -246,10 +252,17 @@ void RasterizerGLES2::initialize() { } #else if (OS::get_singleton()->is_stdout_verbose()) { -+#ifdef X11_ENABLED ++#if defined(X11_ENABLED) && !defined(EGL) + DebugMessageCallbackARB callback = (DebugMessageCallbackARB)glXGetProcAddress((const GLubyte *)"glDebugMessageCallback"); + if (!callback) { + callback = (DebugMessageCallbackARB)glXGetProcAddress((const GLubyte *)"glDebugMessageCallbackKHR"); @@ -315,10 +318,10 @@ index 0000000000..3777596c80 + env.AddPostAction(prog, run_in_subprocess(platform_x11_builders.make_debug_x11)) diff --git a/platform/x11es/context_gl_x11.cpp b/platform/x11es/context_gl_x11.cpp new file mode 100644 -index 0000000000..ab5d655408 +index 0000000000..66e1289f98 --- /dev/null +++ b/platform/x11es/context_gl_x11.cpp -@@ -0,0 +1,306 @@ +@@ -0,0 +1,480 @@ +/**************************************************************************/ +/* context_gl_x11.cpp */ +/**************************************************************************/ @@ -349,6 +352,7 @@ index 0000000000..ab5d655408 +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/**************************************************************************/ + ++#undef NDEBUG +#include "context_gl_x11.h" + +#ifdef X11_ENABLED @@ -356,43 +360,81 @@ index 0000000000..ab5d655408 +#include +#include +#include ++#include + ++#ifndef EGL +#define GLX_GLXEXT_PROTOTYPES +#include +#include ++#else ++#include ++#endif + ++#ifndef EGL +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + +typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); ++#endif + +struct ContextGL_X11_Private { ++#ifndef EGL + ::GLXContext glx_context; + ::GLXContext glx_context_offscreen; ++#else ++ EGLDisplay egl_display; ++ EGLSurface egl_surface; ++ EGLContext egl_context; ++ EGLContext egl_context_offscreen; ++#endif +}; + +void ContextGL_X11::release_current() { ++#ifndef EGL + glXMakeCurrent(x11_display, None, nullptr); ++#else ++ eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); ++#endif +} + +void ContextGL_X11::make_current() { ++#ifndef EGL + glXMakeCurrent(x11_display, x11_window, p->glx_context); ++#else ++ eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface, p->egl_context); ++#endif +} + +bool ContextGL_X11::is_offscreen_available() const { ++#ifndef EGL + return p->glx_context_offscreen; ++#else ++ return p->egl_context_offscreen; ++#endif +} + +void ContextGL_X11::make_offscreen_current() { ++#ifndef EGL + glXMakeCurrent(x11_display, x11_window, p->glx_context_offscreen); ++#else ++ eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface, p->egl_context_offscreen); ++#endif +} + +void ContextGL_X11::release_offscreen_current() { ++#ifndef EGL + glXMakeCurrent(x11_display, None, NULL); ++#else ++ eglMakeCurrent(p->egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); ++#endif +} + +void ContextGL_X11::swap_buffers() { ++#ifndef EGL + glXSwapBuffers(x11_display, x11_window); ++#else ++ eglSwapBuffers(p->egl_display, p->egl_surface); ++#endif +} + +static bool ctxErrorOccurred = false; @@ -415,6 +457,7 @@ index 0000000000..ab5d655408 +} + +Error ContextGL_X11::initialize() { ++#ifndef EGL + //const char *extensions = glXQueryExtensionsString(x11_display, DefaultScreen(x11_display)); + + GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB"); @@ -536,6 +579,107 @@ index 0000000000..ab5d655408 + glXMakeCurrent(x11_display, x11_window, p->glx_context); + + XFree(vi); ++#else ++ p->egl_display = eglGetDisplay((EGLNativeDisplayType)x11_display); ++ if (p->egl_display == EGL_NO_DISPLAY) { ++ print_error("Got no EGL display."); ++ assert(false); ++ } ++ ++ if (!eglInitialize(p->egl_display, &egl_major, ++ &egl_minor)) { ++ print_error("Unable to initialize EGL"); ++ assert(false); ++ } ++ print_line("Initialized EGL version " + itos(egl_major) + "." + itos(egl_minor)); ++ EGLint egl_config_constraints[] = { EGL_RED_SIZE, 8, ++ EGL_GREEN_SIZE, 8, ++ EGL_BLUE_SIZE, 8, ++ EGL_ALPHA_SIZE, 0, ++ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, ++ EGL_CONFIG_CAVEAT, EGL_NONE, ++ EGL_NONE }; ++ EGLConfig egl_conf; ++ EGLint num_config; ++ if (!eglChooseConfig(p->egl_display, egl_config_constraints, &egl_conf, 1, ++ &num_config)) { ++ print_error("Failed to choose config (eglError: " + itos(eglGetError()) + ")"); ++ assert(false); ++ } ++ if (num_config == 0) { ++ print_error("No egl config found"); ++ assert(false); ++ } ++ XVisualInfo x11_visual_info_template; ++ if (!eglGetConfigAttrib(p->egl_display, ++ egl_conf, ++ EGL_NATIVE_VISUAL_ID, ++ (EGLint*) &x11_visual_info_template.visualid)) ++ { ++ print_error("Can't get visual from config"); ++ assert(false); ++ } ++ print_line("native visual id: " + itos(x11_visual_info_template.visualid)); ++ int num_visuals; ++ XVisualInfo *vi = XGetVisualInfo(x11_display, ++ VisualIDMask, ++ &x11_visual_info_template, ++ &num_visuals); ++ print_line("num visuals: " + itos(num_visuals)); ++ if (num_visuals > 0) { ++ assert(vi); ++ assert(vi->screen); ++ assert(vi->visual); ++ XSetWindowAttributes swa; ++ swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); ++ assert(swa.colormap); ++ swa.border_pixel = 0; ++ swa.event_mask = StructureNotifyMask; ++ unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; ++ swa.background_pixmap = None; ++ swa.background_pixel = 0; ++ swa.border_pixmap = None; ++ valuemask |= CWBackPixel; ++ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); ++ } else { ++ XSetWindowAttributes swa; ++ swa.border_pixel = 0; ++ swa.event_mask = StructureNotifyMask; ++ unsigned long valuemask = CWBorderPixel | CWEventMask; ++ swa.background_pixmap = None; ++ swa.background_pixel = 0; ++ swa.border_pixmap = None; ++ valuemask |= CWBackPixel; ++ x11_window = XCreateWindow(x11_display, DefaultRootWindow(x11_display), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, CopyFromParent, InputOutput, CopyFromParent, valuemask, &swa); ++ } ++ XStoreName(x11_display, x11_window, "Godot Engine"); ++ ++ ERR_FAIL_COND_V(!x11_window, ERR_UNCONFIGURED); ++ set_class_hint(x11_display, x11_window); ++ ++ if (!OS::get_singleton()->is_no_window_mode_enabled()) { ++ XMapWindow(x11_display, x11_window); ++ } ++ p->egl_surface = ++ eglCreateWindowSurface(p->egl_display, egl_conf, x11_window, NULL); ++ ++ //// egl-contexts collect all state descriptions needed required for operation ++ EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; ++ p->egl_context = eglCreateContext(p->egl_display, egl_conf, ++ EGL_NO_CONTEXT, ctxattr); ++ if (p->egl_context == EGL_NO_CONTEXT) { ++ print_error("Unable to create EGL context (eglError: " + itos(eglGetError())); ++ assert(false); ++ } ++ p->egl_context_offscreen = eglCreateContext(p->egl_display, egl_conf, ++ EGL_NO_CONTEXT, ctxattr); ++ ++ XSync(x11_display, False); ++ eglMakeCurrent(p->egl_display, p->egl_surface, p->egl_surface, p->egl_context); ++ if (vi) ++ XFree(vi); ++ ++#endif + + return OK; +} @@ -554,6 +698,7 @@ index 0000000000..ab5d655408 + return xwa.height; +} + ++#ifndef EGL +void *ContextGL_X11::get_glx_context() { + if (p != nullptr) { + return p->glx_context; @@ -561,8 +706,18 @@ index 0000000000..ab5d655408 + return nullptr; + } +} ++#else ++void *ContextGL_X11::get_egl_context() { ++ if (p != nullptr) { ++ return p->egl_context; ++ } else { ++ return nullptr; ++ } ++} ++#endif + +void ContextGL_X11::set_use_vsync(bool p_use) { ++#ifndef EGL + static bool setup = false; + static PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr; + static PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalMESA = nullptr; @@ -592,6 +747,10 @@ index 0000000000..ab5d655408 + } else { + return; + } ++#else ++ int val = p_use ? 1 : 0; ++ eglSwapInterval(p->egl_display, val); ++#endif + use_vsync = p_use; +} +bool ContextGL_X11::is_using_vsync() const { @@ -603,23 +762,41 @@ index 0000000000..ab5d655408 + default_video_mode = p_default_video_mode; + x11_display = p_x11_display; + ++#ifndef EGL + context_type = p_context_type; -+ ++#endif + double_buffer = false; + direct_render = false; ++#ifndef EGL + glx_minor = glx_major = 0; ++#else ++ egl_minor = egl_major = 0; ++#endif + p = memnew(ContextGL_X11_Private); ++#ifndef EGL + p->glx_context = nullptr; + p->glx_context_offscreen = nullptr; ++#else ++ p->egl_display = EGL_NO_DISPLAY; ++ p->egl_surface = EGL_NO_SURFACE; ++ p->egl_context = EGL_NO_CONTEXT; ++ p->egl_context_offscreen = EGL_NO_CONTEXT; ++#endif + use_vsync = false; +} + +ContextGL_X11::~ContextGL_X11() { + release_current(); ++#ifndef EGL + glXDestroyContext(x11_display, p->glx_context); + if (p->glx_context_offscreen) { + glXDestroyContext(x11_display, p->glx_context_offscreen); + } ++#else ++ eglDestroyContext(p->egl_display, p->egl_context); ++ eglDestroyContext(p->egl_display, p->egl_context_offscreen); ++ ++#endif + memdelete(p); +} + @@ -627,10 +804,10 @@ index 0000000000..ab5d655408 +#endif diff --git a/platform/x11es/context_gl_x11.h b/platform/x11es/context_gl_x11.h new file mode 100644 -index 0000000000..7ac2d2d97c +index 0000000000..769ee374ea --- /dev/null +++ b/platform/x11es/context_gl_x11.h -@@ -0,0 +1,89 @@ +@@ -0,0 +1,101 @@ +/**************************************************************************/ +/* context_gl_x11.h */ +/**************************************************************************/ @@ -671,6 +848,10 @@ index 0000000000..7ac2d2d97c +#include "core/os/os.h" +#include +#include ++#define EGL ++#ifdef EGL ++#include ++#endif + +struct ContextGL_X11_Private; + @@ -690,9 +871,13 @@ index 0000000000..7ac2d2d97c + ::Window &x11_window; + bool double_buffer; + bool direct_render; ++#ifndef EGL + int glx_minor, glx_major; -+ bool use_vsync; + ContextType context_type; ++#else ++ int egl_minor, egl_major; ++#endif ++ bool use_vsync; + +public: + void release_current(); @@ -700,7 +885,11 @@ index 0000000000..7ac2d2d97c + void swap_buffers(); + int get_window_width(); + int get_window_height(); ++#ifndef EGL + void *get_glx_context(); ++#else ++ void *get_egl_context(); ++#endif + + bool is_offscreen_available() const; + void make_offscreen_current(); @@ -1393,10 +1582,10 @@ index 0000000000..39271b3037 + env.Append(LIBS=["atomic"]) diff --git a/platform/x11es/detect_prime.cpp b/platform/x11es/detect_prime.cpp new file mode 100644 -index 0000000000..49dfd207cc +index 0000000000..48a4049383 --- /dev/null +++ b/platform/x11es/detect_prime.cpp -@@ -0,0 +1,246 @@ +@@ -0,0 +1,315 @@ +/**************************************************************************/ +/* detect_prime.cpp */ +/**************************************************************************/ @@ -1436,9 +1625,15 @@ index 0000000000..49dfd207cc +#include "core/ustring.h" + +#include ++#define EGL + ++#ifndef EGL +#include +#include ++#else ++#include ++#include ++#endif +#include +#include + @@ -1447,11 +1642,14 @@ index 0000000000..49dfd207cc +#include +#include +#include ++#include + ++#ifndef EGL +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 + +typedef GLXContext (*GLXCREATECONTEXTATTRIBSARBPROC)(Display *, GLXFBConfig, GLXContext, Bool, const int *); ++#endif + +struct vendor { + const char *glxvendor; @@ -1474,6 +1672,7 @@ index 0000000000..49dfd207cc +void create_context() { + Display *x11_display = XOpenDisplay(nullptr); + Window x11_window; ++#ifndef EGL + GLXContext glx_context; + + GLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB = (GLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress((const GLubyte *)"glXCreateContextAttribsARB"); @@ -1525,6 +1724,65 @@ index 0000000000..49dfd207cc + } + + glXMakeCurrent(x11_display, x11_window, glx_context); ++#else ++ EGLDisplay egl_display = eglGetDisplay((EGLNativeDisplayType)x11_display); ++ if (egl_display == EGL_NO_DISPLAY) ++ exit(1); ++ int egl_major, egl_minor; ++ if (!eglInitialize(egl_display, &egl_major, ++ &egl_minor)) ++ exit(1); ++ EGLint egl_config_constraints[] = { EGL_RED_SIZE, 1, ++ EGL_GREEN_SIZE, 1, ++ EGL_BLUE_SIZE, 1, ++ EGL_ALPHA_SIZE, 0, ++ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, ++ EGL_CONFIG_CAVEAT, EGL_NONE, ++ EGL_NONE }; ++ EGLConfig egl_conf; ++ EGLint num_config; ++ if (!eglChooseConfig(egl_display, egl_config_constraints, &egl_conf, 1, ++ &num_config)) ++ exit(1); ++ if (num_config > 0) ++ exit(1); ++ XVisualInfo x11_visual_info_template; ++ if (!eglGetConfigAttrib(egl_display, ++ egl_conf, ++ EGL_NATIVE_VISUAL_ID, ++ (EGLint*) &x11_visual_info_template.visualid)) ++ exit(1); ++ int num_visuals; ++ XVisualInfo *vi = XGetVisualInfo(x11_display, ++ VisualIDMask, ++ &x11_visual_info_template, ++ &num_visuals); ++ assert(vi); ++ XSetWindowAttributes swa; ++ swa.event_mask = StructureNotifyMask; ++ swa.border_pixel = 0; ++ unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; ++ swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); ++ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, 10, 10, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); ++ ++ if (!x11_window) { ++ exit(1); ++ } ++ EGLSurface egl_surface = ++ eglCreateWindowSurface(egl_display, egl_conf, x11_window, NULL); ++ ++ //// egl-contexts collect all state descriptions needed required for operation ++ EGLint ctxattr[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; ++ EGLContext egl_context = eglCreateContext(egl_display, egl_conf, ++ EGL_NO_CONTEXT, ctxattr); ++ if (egl_context == EGL_NO_CONTEXT) { ++ print_error("Unable to create EGL context (eglError: " + itos(eglGetError())); ++ assert(false); ++ } ++ eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context); ++ ++#endif ++ + XFree(vi); +} + @@ -5794,10 +6052,10 @@ HcmV?d00001 diff --git a/platform/x11es/os_x11.cpp b/platform/x11es/os_x11.cpp new file mode 100644 -index 0000000000..1d8c9badfb +index 0000000000..26e3f1c4f9 --- /dev/null +++ b/platform/x11es/os_x11.cpp -@@ -0,0 +1,4493 @@ +@@ -0,0 +1,4497 @@ +/**************************************************************************/ +/* os_x11.cpp */ +/**************************************************************************/ @@ -7826,7 +8084,11 @@ index 0000000000..1d8c9badfb + case WINDOW_VIEW: + return nullptr; // Do we have a value to return here? + case OPENGL_CONTEXT: ++#ifndef EGL + return context_gl->get_glx_context(); ++#else ++ return context_gl->get_egl_context(); ++#endif + default: + return nullptr; + }