mirror of
https://github.com/godotengine/godot.git
synced 2025-10-19 16:03:29 +00:00
OpenXR: Add support for Wayland on Linux
This commit is contained in:
parent
2e14492879
commit
256699ee31
15 changed files with 149 additions and 9 deletions
2
.github/workflows/linux_builds.yml
vendored
2
.github/workflows/linux_builds.yml
vendored
|
@ -106,7 +106,7 @@ jobs:
|
||||||
# TODO: Figure out somehow how to embed this one.
|
# TODO: Figure out somehow how to embed this one.
|
||||||
- name: wayland-scanner dependency
|
- name: wayland-scanner dependency
|
||||||
run: |
|
run: |
|
||||||
sudo apt-get install libwayland-bin
|
sudo apt-get install libwayland-bin libegl-dev
|
||||||
|
|
||||||
- name: Free disk space on runner
|
- name: Free disk space on runner
|
||||||
run: |
|
run: |
|
||||||
|
|
|
@ -2138,12 +2138,14 @@
|
||||||
<constant name="DISPLAY_HANDLE" value="0" enum="HandleType">
|
<constant name="DISPLAY_HANDLE" value="0" enum="HandleType">
|
||||||
Display handle:
|
Display handle:
|
||||||
- Linux (X11): [code]X11::Display*[/code] for the display.
|
- Linux (X11): [code]X11::Display*[/code] for the display.
|
||||||
|
- Linux (Wayland): [code]wl_display[/code] for the display.
|
||||||
- Android: [code]EGLDisplay[/code] for the display.
|
- Android: [code]EGLDisplay[/code] for the display.
|
||||||
</constant>
|
</constant>
|
||||||
<constant name="WINDOW_HANDLE" value="1" enum="HandleType">
|
<constant name="WINDOW_HANDLE" value="1" enum="HandleType">
|
||||||
Window handle:
|
Window handle:
|
||||||
- Windows: [code]HWND[/code] for the window.
|
- Windows: [code]HWND[/code] for the window.
|
||||||
- Linux (X11): [code]X11::Window*[/code] for the window.
|
- Linux (X11): [code]X11::Window*[/code] for the window.
|
||||||
|
- Linux (Wayland): [code]wl_surface[/code] for the window.
|
||||||
- macOS: [code]NSWindow*[/code] for the window.
|
- macOS: [code]NSWindow*[/code] for the window.
|
||||||
- iOS: [code]UIViewController*[/code] for the view controller.
|
- iOS: [code]UIViewController*[/code] for the view controller.
|
||||||
- Android: [code]jObject[/code] for the activity.
|
- Android: [code]jObject[/code] for the activity.
|
||||||
|
@ -2158,9 +2160,20 @@
|
||||||
OpenGL context (only with the GL Compatibility renderer):
|
OpenGL context (only with the GL Compatibility renderer):
|
||||||
- Windows: [code]HGLRC[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
|
- Windows: [code]HGLRC[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
|
||||||
- Linux (X11): [code]GLXContext*[/code] for the window.
|
- Linux (X11): [code]GLXContext*[/code] for the window.
|
||||||
|
- Linux (Wayland): [code]EGLContext[/code] for the window.
|
||||||
- macOS: [code]NSOpenGLContext*[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
|
- macOS: [code]NSOpenGLContext*[/code] for the window (native GL), or [code]EGLContext[/code] for the window (ANGLE).
|
||||||
- Android: [code]EGLContext[/code] for the window.
|
- Android: [code]EGLContext[/code] for the window.
|
||||||
</constant>
|
</constant>
|
||||||
|
<constant name="EGL_DISPLAY" value="4" enum="HandleType">
|
||||||
|
- Windows: [code]EGLDisplay[/code] for the window (ANGLE).
|
||||||
|
- macOS: [code]EGLDisplay[/code] for the window (ANGLE).
|
||||||
|
- Linux (Wayland): [code]EGLDisplay[/code] for the window.
|
||||||
|
</constant>
|
||||||
|
<constant name="EGL_CONFIG" value="5" enum="HandleType">
|
||||||
|
- Windows: [code]EGLConfig[/code] for the window (ANGLE).
|
||||||
|
- macOS: [code]EGLConfig[/code] for the window (ANGLE).
|
||||||
|
- Linux (Wayland): [code]EGLConfig[/code] for the window.
|
||||||
|
</constant>
|
||||||
<constant name="TTS_UTTERANCE_STARTED" value="0" enum="TTSUtteranceEvent">
|
<constant name="TTS_UTTERANCE_STARTED" value="0" enum="TTSUtteranceEvent">
|
||||||
Utterance has begun to be spoken.
|
Utterance has begun to be spoken.
|
||||||
</constant>
|
</constant>
|
||||||
|
|
|
@ -351,6 +351,30 @@ EGLContext EGLManager::get_context(DisplayServer::WindowID p_window_id) {
|
||||||
return display.egl_context;
|
return display.egl_context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EGLDisplay EGLManager::get_display(DisplayServer::WindowID p_window_id) {
|
||||||
|
GLWindow &glwindow = windows[p_window_id];
|
||||||
|
|
||||||
|
if (!glwindow.initialized) {
|
||||||
|
return EGL_NO_CONTEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLDisplay &display = displays[glwindow.gldisplay_id];
|
||||||
|
|
||||||
|
return display.egl_display;
|
||||||
|
}
|
||||||
|
|
||||||
|
EGLConfig EGLManager::get_config(DisplayServer::WindowID p_window_id) {
|
||||||
|
GLWindow &glwindow = windows[p_window_id];
|
||||||
|
|
||||||
|
if (!glwindow.initialized) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLDisplay &display = displays[glwindow.gldisplay_id];
|
||||||
|
|
||||||
|
return display.egl_config;
|
||||||
|
}
|
||||||
|
|
||||||
Error EGLManager::initialize(void *p_native_display) {
|
Error EGLManager::initialize(void *p_native_display) {
|
||||||
#if defined(GLAD_ENABLED) && !defined(EGL_STATIC)
|
#if defined(GLAD_ENABLED) && !defined(EGL_STATIC)
|
||||||
// Loading EGL with a new display gets us just the bare minimum API. We'll then
|
// Loading EGL with a new display gets us just the bare minimum API. We'll then
|
||||||
|
|
|
@ -106,6 +106,8 @@ public:
|
||||||
bool is_using_vsync() const;
|
bool is_using_vsync() const;
|
||||||
|
|
||||||
EGLContext get_context(DisplayServer::WindowID p_window_id);
|
EGLContext get_context(DisplayServer::WindowID p_window_id);
|
||||||
|
EGLDisplay get_display(DisplayServer::WindowID p_window_id);
|
||||||
|
EGLConfig get_config(DisplayServer::WindowID p_window_id);
|
||||||
|
|
||||||
Error initialize(void *p_native_display = nullptr);
|
Error initialize(void *p_native_display = nullptr);
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ elif env["platform"] == "linuxbsd":
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_XLIB"])
|
||||||
|
|
||||||
if env["wayland"]:
|
if env["wayland"]:
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_WAYLAND"])
|
env_openxr.AppendUnique(CPPDEFINES=["XR_USE_PLATFORM_EGL"])
|
||||||
|
|
||||||
# FIXME: Review what needs to be set for Android and macOS.
|
# FIXME: Review what needs to be set for Android and macOS.
|
||||||
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
|
env_openxr.AppendUnique(CPPDEFINES=["HAVE_SECURE_GETENV"])
|
||||||
|
|
|
@ -64,6 +64,9 @@ HashMap<String, bool *> OpenXROpenGLExtension::get_requested_extensions() {
|
||||||
#else
|
#else
|
||||||
request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr;
|
request_extensions[XR_KHR_OPENGL_ENABLE_EXTENSION_NAME] = nullptr;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
|
||||||
|
request_extensions[XR_MNDX_EGL_ENABLE_EXTENSION_NAME] = &egl_extension_enabled;
|
||||||
|
#endif
|
||||||
|
|
||||||
return request_extensions;
|
return request_extensions;
|
||||||
}
|
}
|
||||||
|
@ -128,9 +131,14 @@ bool OpenXROpenGLExtension::check_graphics_api_support(XrVersion p_desired_versi
|
||||||
XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl;
|
XrGraphicsBindingOpenGLWin32KHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||||
#elif defined(ANDROID_ENABLED)
|
#elif defined(ANDROID_ENABLED)
|
||||||
XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl;
|
XrGraphicsBindingOpenGLESAndroidKHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||||
#elif defined(X11_ENABLED)
|
#elif defined(LINUXBSD_ENABLED)
|
||||||
|
#ifdef X11_ENABLED
|
||||||
XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl;
|
XrGraphicsBindingOpenGLXlibKHR OpenXROpenGLExtension::graphics_binding_gl;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef EGL_ENABLED
|
||||||
|
XrGraphicsBindingEGLMNDX OpenXROpenGLExtension::graphics_binding_egl;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
|
void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_next_pointer) {
|
||||||
XrVersion desired_version = XR_MAKE_VERSION(3, 3, 0);
|
XrVersion desired_version = XR_MAKE_VERSION(3, 3, 0);
|
||||||
|
@ -142,10 +150,6 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
|
||||||
|
|
||||||
DisplayServer *display_server = DisplayServer::get_singleton();
|
DisplayServer *display_server = DisplayServer::get_singleton();
|
||||||
|
|
||||||
#ifdef WAYLAND_ENABLED
|
|
||||||
ERR_FAIL_COND_V_MSG(display_server->get_name() == "Wayland", p_next_pointer, "OpenXR is not yet supported on OpenGL Wayland.");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
|
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_WIN32_KHR,
|
||||||
graphics_binding_gl.next = p_next_pointer;
|
graphics_binding_gl.next = p_next_pointer;
|
||||||
|
@ -159,7 +163,23 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
|
||||||
graphics_binding_gl.display = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE);
|
graphics_binding_gl.display = (void *)display_server->window_get_native_handle(DisplayServer::DISPLAY_HANDLE);
|
||||||
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
|
graphics_binding_gl.config = (EGLConfig)0; // https://github.com/KhronosGroup/OpenXR-SDK-Source/blob/master/src/tests/hello_xr/graphicsplugin_opengles.cpp#L122
|
||||||
graphics_binding_gl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
|
graphics_binding_gl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
|
||||||
#elif defined(X11_ENABLED)
|
#else
|
||||||
|
#if defined(EGL_ENABLED) && defined(WAYLAND_ENABLED)
|
||||||
|
if (display_server->get_name() == "Wayland") {
|
||||||
|
ERR_FAIL_COND_V_MSG(!egl_extension_enabled, p_next_pointer, "OpenXR cannot initialize on Wayland without the XR_MNDX_egl_enable extension.");
|
||||||
|
|
||||||
|
graphics_binding_egl.type = XR_TYPE_GRAPHICS_BINDING_EGL_MNDX;
|
||||||
|
graphics_binding_egl.next = p_next_pointer;
|
||||||
|
|
||||||
|
graphics_binding_egl.getProcAddress = eglGetProcAddress;
|
||||||
|
graphics_binding_egl.display = (void *)display_server->window_get_native_handle(DisplayServer::EGL_DISPLAY);
|
||||||
|
graphics_binding_egl.config = (void *)display_server->window_get_native_handle(DisplayServer::EGL_CONFIG);
|
||||||
|
graphics_binding_egl.context = (void *)display_server->window_get_native_handle(DisplayServer::OPENGL_CONTEXT);
|
||||||
|
|
||||||
|
return &graphics_binding_egl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(X11_ENABLED)
|
||||||
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
|
graphics_binding_gl.type = XR_TYPE_GRAPHICS_BINDING_OPENGL_XLIB_KHR;
|
||||||
graphics_binding_gl.next = p_next_pointer;
|
graphics_binding_gl.next = p_next_pointer;
|
||||||
|
|
||||||
|
@ -175,8 +195,13 @@ void *OpenXROpenGLExtension::set_session_create_and_get_next_pointer(void *p_nex
|
||||||
graphics_binding_gl.visualid = 0;
|
graphics_binding_gl.visualid = 0;
|
||||||
graphics_binding_gl.glxFBConfig = 0;
|
graphics_binding_gl.glxFBConfig = 0;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WIN32) || defined(ANDROID_ENABLED) || defined(X11_ENABLED)
|
||||||
return &graphics_binding_gl;
|
return &graphics_binding_gl;
|
||||||
|
#else
|
||||||
|
return p_next_pointer;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
|
void OpenXROpenGLExtension::get_usable_swapchain_formats(Vector<int64_t> &p_usable_swap_chains) {
|
||||||
|
|
|
@ -64,8 +64,17 @@ private:
|
||||||
static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
|
static XrGraphicsBindingOpenGLWin32KHR graphics_binding_gl;
|
||||||
#elif defined(ANDROID_ENABLED)
|
#elif defined(ANDROID_ENABLED)
|
||||||
static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl;
|
static XrGraphicsBindingOpenGLESAndroidKHR graphics_binding_gl;
|
||||||
#else // Linux/X11
|
#elif defined(LINUXBSD_ENABLED)
|
||||||
|
#ifdef X11_ENABLED
|
||||||
static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl;
|
static XrGraphicsBindingOpenGLXlibKHR graphics_binding_gl;
|
||||||
|
#endif
|
||||||
|
#ifdef EGL_ENABLED
|
||||||
|
static XrGraphicsBindingEGLMNDX graphics_binding_egl;
|
||||||
|
|
||||||
|
bool egl_extension_enabled = false;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#error "OpenXR with OpenGL isn't supported on this platform"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct SwapchainGraphicsData {
|
struct SwapchainGraphicsData {
|
||||||
|
|
|
@ -49,6 +49,13 @@
|
||||||
#else
|
#else
|
||||||
#define XR_USE_GRAPHICS_API_OPENGL
|
#define XR_USE_GRAPHICS_API_OPENGL
|
||||||
#endif // ANDROID_ENABLED
|
#endif // ANDROID_ENABLED
|
||||||
|
#if defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
|
||||||
|
#ifdef GLAD_ENABLED
|
||||||
|
#include "thirdparty/glad/glad/egl.h"
|
||||||
|
#else
|
||||||
|
#include <EGL/egl.h>
|
||||||
|
#endif // GLAD_ENABLED
|
||||||
|
#endif // defined(LINUXBSD_ENABLED) && defined(EGL_ENABLED)
|
||||||
#ifdef X11_ENABLED
|
#ifdef X11_ENABLED
|
||||||
#define GL_GLEXT_PROTOTYPES 1
|
#define GL_GLEXT_PROTOTYPES 1
|
||||||
#define GL3_PROTOTYPES 1
|
#define GL3_PROTOTYPES 1
|
||||||
|
|
|
@ -382,6 +382,14 @@ int64_t DisplayServerAndroid::window_get_native_handle(HandleType p_handle_type,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case EGL_DISPLAY: {
|
||||||
|
// @todo Find a way to get this from the Java side.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case EGL_CONFIG: {
|
||||||
|
// @todo Find a way to get this from the Java side.
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -627,6 +627,18 @@ int64_t DisplayServerWayland::window_get_native_handle(HandleType p_handle_type,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
} break;
|
} break;
|
||||||
|
case EGL_DISPLAY: {
|
||||||
|
if (egl_manager) {
|
||||||
|
return (int64_t)egl_manager->get_display(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case EGL_CONFIG: {
|
||||||
|
if (egl_manager) {
|
||||||
|
return (int64_t)egl_manager->get_config(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif // GLES3_ENABLED
|
#endif // GLES3_ENABLED
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -1861,6 +1861,18 @@ int64_t DisplayServerX11::window_get_native_handle(HandleType p_handle_type, Win
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case EGL_DISPLAY: {
|
||||||
|
if (gl_manager_egl) {
|
||||||
|
return (int64_t)gl_manager_egl->get_display(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case EGL_CONFIG: {
|
||||||
|
if (gl_manager_egl) {
|
||||||
|
return (int64_t)gl_manager_egl->get_config(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -2666,6 +2666,18 @@ int64_t DisplayServerMacOS::window_get_native_handle(HandleType p_handle_type, W
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case EGL_DISPLAY: {
|
||||||
|
if (gl_manager_angle) {
|
||||||
|
return (int64_t)gl_manager_angle->get_display(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case EGL_CONFIG: {
|
||||||
|
if (gl_manager_angle) {
|
||||||
|
return (int64_t)gl_manager_angle->get_config(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1649,6 +1649,18 @@ int64_t DisplayServerWindows::window_get_native_handle(HandleType p_handle_type,
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case EGL_DISPLAY: {
|
||||||
|
if (gl_manager_angle) {
|
||||||
|
return (int64_t)gl_manager_angle->get_display(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
case EGL_CONFIG: {
|
||||||
|
if (gl_manager_angle) {
|
||||||
|
return (int64_t)gl_manager_angle->get_config(p_window);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
default: {
|
default: {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1142,6 +1142,8 @@ void DisplayServer::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(WINDOW_HANDLE);
|
BIND_ENUM_CONSTANT(WINDOW_HANDLE);
|
||||||
BIND_ENUM_CONSTANT(WINDOW_VIEW);
|
BIND_ENUM_CONSTANT(WINDOW_VIEW);
|
||||||
BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
|
BIND_ENUM_CONSTANT(OPENGL_CONTEXT);
|
||||||
|
BIND_ENUM_CONSTANT(EGL_DISPLAY);
|
||||||
|
BIND_ENUM_CONSTANT(EGL_CONFIG);
|
||||||
|
|
||||||
BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED);
|
BIND_ENUM_CONSTANT(TTS_UTTERANCE_STARTED);
|
||||||
BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED);
|
BIND_ENUM_CONSTANT(TTS_UTTERANCE_ENDED);
|
||||||
|
|
|
@ -82,6 +82,8 @@ public:
|
||||||
WINDOW_HANDLE,
|
WINDOW_HANDLE,
|
||||||
WINDOW_VIEW,
|
WINDOW_VIEW,
|
||||||
OPENGL_CONTEXT,
|
OPENGL_CONTEXT,
|
||||||
|
EGL_DISPLAY,
|
||||||
|
EGL_CONFIG,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Context {
|
enum Context {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue