summaryrefslogtreecommitdiff
path: root/platform/x11
diff options
context:
space:
mode:
Diffstat (limited to 'platform/x11')
-rw-r--r--platform/x11/SCsub1
-rw-r--r--platform/x11/detect.py15
-rw-r--r--platform/x11/os_x11.cpp277
-rw-r--r--platform/x11/os_x11.h18
-rw-r--r--platform/x11/vulkan_context_x11.cpp57
-rw-r--r--platform/x11/vulkan_context_x11.h48
6 files changed, 283 insertions, 133 deletions
diff --git a/platform/x11/SCsub b/platform/x11/SCsub
index 3d5aa15208..9027c244be 100644
--- a/platform/x11/SCsub
+++ b/platform/x11/SCsub
@@ -7,6 +7,7 @@ import platform_x11_builders
common_x11 = [
"context_gl_x11.cpp",
+ "vulkan_context_x11.cpp",
"crash_handler_x11.cpp",
"os_x11.cpp",
"key_mapping_x11.cpp",
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index bd5e5e0812..9d5affcb3c 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -318,8 +318,19 @@ def configure(env):
env.ParseConfig('pkg-config zlib --cflags --libs')
env.Prepend(CPPPATH=['#platform/x11'])
- env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED'])
- env.Append(LIBS=['GL', 'pthread'])
+ env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED'])
+
+ env.Append(CPPDEFINES=['VULKAN_ENABLED'])
+ if not env['builtin_vulkan']:
+ env.ParseConfig('pkg-config vulkan --cflags --libs')
+ if not env['builtin_glslang']:
+ # No pkgconfig file for glslang so far
+ env.Append(LIBS=['glslang', 'SPIRV'])
+
+ #env.Append(CPPDEFINES=['OPENGL_ENABLED'])
+ env.Append(LIBS=['GL'])
+
+ env.Append(LIBS=['pthread'])
if (platform.system() == "Linux"):
env.Append(LIBS=['dl'])
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 1cd763853c..338194fcae 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -33,10 +33,17 @@
#include "core/os/dir_access.h"
#include "core/print_string.h"
-#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/gles3/rasterizer_gles3.h"
#include "errno.h"
#include "key_mapping_x11.h"
+
+#if defined(OPENGL_ENABLED)
+#include "drivers/gles2/rasterizer_gles2.h"
+#endif
+
+#if defined(VULKAN_ENABLED)
+#include "servers/visual/rasterizer_rd/rasterizer_rd.h"
+#endif
+
#include "servers/visual/visual_server_raster.h"
#include "servers/visual/visual_server_wrap_mt.h"
@@ -230,137 +237,126 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
XFree(imvalret);
}
-/*
- char* windowid = getenv("GODOT_WINDOWID");
- if (windowid) {
+ //!!!!!!!!!!!!!!!!!!!!!!!!!!
+ //TODO - do Vulkan and GLES2 support checks, driver selection and fallback
+ video_driver_index = p_video_driver;
+ print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]");
+ //!!!!!!!!!!!!!!!!!!!!!!!!!!
- //freopen("/home/punto/stdout", "w", stdout);
- //reopen("/home/punto/stderr", "w", stderr);
- x11_window = atol(windowid);
+ //Create window
- XWindowAttributes xwa;
- XGetWindowAttributes(x11_display,x11_window,&xwa);
+ long visualMask = VisualScreenMask;
+ int numberOfVisuals;
+ XVisualInfo vInfoTemplate = {};
+ vInfoTemplate.screen = DefaultScreen(x11_display);
+ XVisualInfo *visualInfo = XGetVisualInfo(x11_display, visualMask, &vInfoTemplate, &numberOfVisuals);
- current_videomode.width = xwa.width;
- current_videomode.height = xwa.height;
- };
- */
+ Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, vInfoTemplate.screen), visualInfo->visual, AllocNone);
-// maybe contextgl wants to be in charge of creating the window
-#if defined(OPENGL_ENABLED)
- if (getenv("DRI_PRIME") == NULL) {
- int use_prime = -1;
+ XSetWindowAttributes windowAttributes = {};
+ windowAttributes.colormap = colormap;
+ windowAttributes.background_pixel = 0xFFFFFFFF;
+ windowAttributes.border_pixel = 0;
+ windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask;
- if (getenv("PRIMUS_DISPLAY") ||
- getenv("PRIMUS_libGLd") ||
- getenv("PRIMUS_libGLa") ||
- getenv("PRIMUS_libGL") ||
- getenv("PRIMUS_LOAD_GLOBAL") ||
- getenv("BUMBLEBEE_SOCKET")) {
+ unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask;
+ x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes);
- print_verbose("Optirun/primusrun detected. Skipping GPU detection");
- use_prime = 0;
- }
+ //set_class_hint(x11_display, x11_window);
+ XMapWindow(x11_display, x11_window);
+ XFlush(x11_display);
- if (getenv("LD_LIBRARY_PATH")) {
- String ld_library_path(getenv("LD_LIBRARY_PATH"));
- Vector<String> libraries = ld_library_path.split(":");
+ XSync(x11_display, False);
+ //XSetErrorHandler(oldHandler);
- for (int i = 0; i < libraries.size(); ++i) {
- if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
- FileAccess::exists(libraries[i] + "/libGL.so")) {
+ XFree(visualInfo);
- print_verbose("Custom libGL override detected. Skipping GPU detection");
- use_prime = 0;
- }
+ // Init context and rendering device
+#if defined(OPENGL_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+ if (getenv("DRI_PRIME") == NULL) {
+ int use_prime = -1;
+
+ if (getenv("PRIMUS_DISPLAY") ||
+ getenv("PRIMUS_libGLd") ||
+ getenv("PRIMUS_libGLa") ||
+ getenv("PRIMUS_libGL") ||
+ getenv("PRIMUS_LOAD_GLOBAL") ||
+ getenv("BUMBLEBEE_SOCKET")) {
+
+ print_verbose("Optirun/primusrun detected. Skipping GPU detection");
+ use_prime = 0;
}
- }
-
- if (use_prime == -1) {
- print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
- use_prime = detect_prime();
- }
- if (use_prime) {
- print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
- print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
- setenv("DRI_PRIME", "1", 1);
- }
- }
-
- ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE;
-
- if (p_video_driver == VIDEO_DRIVER_GLES2) {
- opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
- }
-
- bool editor = Engine::get_singleton()->is_editor_hint();
- bool gl_initialization_error = false;
+ if (getenv("LD_LIBRARY_PATH")) {
+ String ld_library_path(getenv("LD_LIBRARY_PATH"));
+ Vector<String> libraries = ld_library_path.split(":");
- context_gl = NULL;
- while (!context_gl) {
- context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+ for (int i = 0; i < libraries.size(); ++i) {
+ if (FileAccess::exists(libraries[i] + "/libGL.so.1") ||
+ FileAccess::exists(libraries[i] + "/libGL.so")) {
- if (context_gl->initialize() != OK) {
- memdelete(context_gl);
- context_gl = NULL;
-
- if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) {
- if (p_video_driver == VIDEO_DRIVER_GLES2) {
- gl_initialization_error = true;
- break;
+ print_verbose("Custom libGL override detected. Skipping GPU detection");
+ use_prime = 0;
+ }
}
+ }
- p_video_driver = VIDEO_DRIVER_GLES2;
- opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
- } else {
- gl_initialization_error = true;
- break;
+ if (use_prime == -1) {
+ print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic.");
+ use_prime = detect_prime();
}
- }
- }
- while (true) {
- if (opengl_api_type == ContextGL_X11::GLES_3_0_COMPATIBLE) {
- if (RasterizerGLES3::is_viable() == OK) {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- break;
- } else {
- if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) {
- p_video_driver = VIDEO_DRIVER_GLES2;
- opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
- continue;
- } else {
- gl_initialization_error = true;
- break;
- }
+ if (use_prime) {
+ print_line("Found discrete GPU, setting DRI_PRIME=1 to use it.");
+ print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU.");
+ setenv("DRI_PRIME", "1", 1);
}
}
- if (opengl_api_type == ContextGL_X11::GLES_2_0_COMPATIBLE) {
- if (RasterizerGLES2::is_viable() == OK) {
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- break;
- } else {
- gl_initialization_error = true;
- break;
- }
+ ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE;
+
+ context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type));
+
+ if (context_gles2->initialize() != OK) {
+ memdelete(context_gles2);
+ context_gles2 = NULL;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
}
- }
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n"
- "Please update your drivers or if you have a very old or integrated GPU upgrade it.",
- "Unable to initialize Video driver");
- return ERR_UNAVAILABLE;
+ context_gles2->set_use_vsync(current_videomode.use_vsync);
+
+ if (RasterizerGLES2::is_viable() == OK) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ memdelete(context_gles2);
+ context_gles2 = NULL;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
}
+#endif
+#if defined(VULKAN_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_VULKAN) {
- video_driver_index = p_video_driver;
+ context_vulkan = memnew(VulkanContextX11);
+ if (context_vulkan->initialize() != OK) {
+ memdelete(context_vulkan);
+ context_vulkan = NULL;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
+ if (context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height) == -1) {
+ memdelete(context_vulkan);
+ context_vulkan = NULL;
+ ERR_FAIL_V(ERR_UNAVAILABLE);
+ }
- context_gl->set_use_vsync(current_videomode.use_vsync);
+ //temporary
+ rendering_device_vulkan = memnew(RenderingDeviceVulkan);
+ rendering_device_vulkan->initialize(context_vulkan);
+ RasterizerRD::make_current();
+ }
#endif
visual_server = memnew(VisualServerRaster);
@@ -868,19 +864,35 @@ void OS_X11::finalize() {
cursors_cache.clear();
visual_server->finish();
memdelete(visual_server);
- //memdelete(rasterizer);
memdelete(power_manager);
+#if defined(OPENGL_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+
+ if (context_gles2)
+ memdelete(context_gles2);
+ }
+#endif
+#if defined(VULKAN_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_VULKAN) {
+
+ if (rendering_device_vulkan) {
+ rendering_device_vulkan->finalize();
+ memdelete(rendering_device_vulkan);
+ }
+
+ if (context_vulkan)
+ memdelete(context_vulkan);
+ }
+#endif
+
if (xrandr_handle)
dlclose(xrandr_handle);
XUnmapWindow(x11_display, x11_window);
XDestroyWindow(x11_display, x11_window);
-#if defined(OPENGL_ENABLED)
- memdelete(context_gl);
-#endif
for (int i = 0; i < CURSOR_MAX; i++) {
if (cursors[i] != None)
XFreeCursor(x11_display, cursors[i]);
@@ -2122,6 +2134,12 @@ void OS_X11::_window_changed(XEvent *event) {
current_videomode.width = event->xconfigure.width;
current_videomode.height = event->xconfigure.height;
+
+#if defined(VULKAN_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_VULKAN) {
+ context_vulkan->window_resize(0, current_videomode.width, current_videomode.height);
+ }
+#endif
}
void OS_X11::process_xevents() {
@@ -3010,7 +3028,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
cursors_cache.erase(p_shape);
}
- Ref<Texture> texture = p_cursor;
+ Ref<Texture2D> texture = p_cursor;
Ref<AtlasTexture> atlas_texture = p_cursor;
Ref<Image> image;
Size2 texture_size;
@@ -3106,24 +3124,33 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c
}
void OS_X11::release_rendering_thread() {
-
#if defined(OPENGL_ENABLED)
- context_gl->release_current();
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+ context_gles2->release_current();
+ }
#endif
}
void OS_X11::make_rendering_thread() {
-
#if defined(OPENGL_ENABLED)
- context_gl->make_current();
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+ context_gles2->make_current();
+ }
#endif
}
void OS_X11::swap_buffers() {
-
#if defined(OPENGL_ENABLED)
- context_gl->swap_buffers();
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+ context_gles2->swap_buffers();
+ }
#endif
+ /* not needed for now
+#if defined(VULKAN_ENABLED)
+ if (video_driver_index == VIDEO_DRIVER_VULKAN) {
+ context_vulkan->swap_buffers();
+ }
+#endif*/
}
void OS_X11::alert(const String &p_alert, const String &p_title) {
@@ -3311,19 +3338,13 @@ String OS_X11::get_joy_guid(int p_device) const {
void OS_X11::_set_use_vsync(bool p_enable) {
#if defined(OPENGL_ENABLED)
- if (context_gl)
- context_gl->set_use_vsync(p_enable);
+ if (video_driver_index == VIDEO_DRIVER_GLES2) {
+ if (context_gles2)
+ context_gles2->set_use_vsync(p_enable);
+ }
#endif
}
-/*
-bool OS_X11::is_vsync_enabled() const {
-
- if (context_gl)
- return context_gl->is_using_vsync();
- return true;
-}
-*/
void OS_X11::set_context(int p_context) {
XClassHint *classHint = XAllocClassHint();
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 25b406743b..fd8a981763 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -31,7 +31,6 @@
#ifndef OS_X11_H
#define OS_X11_H
-#include "context_gl_x11.h"
#include "core/os/input.h"
#include "crash_handler_x11.h"
#include "drivers/alsa/audio_driver_alsa.h"
@@ -44,7 +43,15 @@
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
+
+#if defined(OPENGL_ENABLED)
+#include "context_gl_x11.h"
+#endif
+
+#if defined(VULKAN_ENABLED)
+#include "drivers/vulkan/rendering_device_vulkan.h"
+#include "platform/x11/vulkan_context_x11.h"
+#endif
#include <X11/Xcursor/Xcursor.h>
#include <X11/Xlib.h>
@@ -92,8 +99,13 @@ class OS_X11 : public OS_Unix {
int xdnd_version;
#if defined(OPENGL_ENABLED)
- ContextGL_X11 *context_gl;
+ ContextGL_X11 *context_gles2;
#endif
+#if defined(VULKAN_ENABLED)
+ VulkanContextX11 *context_vulkan;
+ RenderingDeviceVulkan *rendering_device_vulkan;
+#endif
+
//Rasterizer *rasterizer;
VisualServer *visual_server;
VideoMode current_videomode;
diff --git a/platform/x11/vulkan_context_x11.cpp b/platform/x11/vulkan_context_x11.cpp
new file mode 100644
index 0000000000..602dbc77a2
--- /dev/null
+++ b/platform/x11/vulkan_context_x11.cpp
@@ -0,0 +1,57 @@
+/*************************************************************************/
+/* vulkan_context_x11.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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. */
+/*************************************************************************/
+
+#include "vulkan_context_x11.h"
+#include <vulkan/vulkan_xlib.h>
+
+const char *VulkanContextX11::_get_platform_surface_extension() const {
+ return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
+}
+
+int VulkanContextX11::window_create(::Window p_window, Display *p_display, int p_width, int p_height) {
+
+ VkXlibSurfaceCreateInfoKHR createInfo;
+ createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR;
+ createInfo.pNext = NULL;
+ createInfo.flags = 0;
+ createInfo.dpy = p_display;
+ createInfo.window = p_window;
+
+ VkSurfaceKHR surface;
+ VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, NULL, &surface);
+ ERR_FAIL_COND_V(err, -1);
+ return _window_create(surface, p_width, p_height);
+}
+
+VulkanContextX11::VulkanContextX11() {
+}
+
+VulkanContextX11::~VulkanContextX11() {
+}
diff --git a/platform/x11/vulkan_context_x11.h b/platform/x11/vulkan_context_x11.h
new file mode 100644
index 0000000000..573f994ea6
--- /dev/null
+++ b/platform/x11/vulkan_context_x11.h
@@ -0,0 +1,48 @@
+/*************************************************************************/
+/* vulkan_context_x11.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* 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 VULKAN_DEVICE_X11_H
+#define VULKAN_DEVICE_X11_H
+
+#include "drivers/vulkan/vulkan_context.h"
+#include <X11/Xlib.h>
+
+class VulkanContextX11 : public VulkanContext {
+
+ virtual const char *_get_platform_surface_extension() const;
+
+public:
+ int window_create(::Window p_window, Display *p_display, int p_width, int p_height);
+
+ VulkanContextX11();
+ ~VulkanContextX11();
+};
+
+#endif // VULKAN_DEVICE_X11_H