diff options
Diffstat (limited to 'platform/x11')
-rw-r--r-- | platform/x11/SCsub | 1 | ||||
-rw-r--r-- | platform/x11/detect.py | 15 | ||||
-rw-r--r-- | platform/x11/os_x11.cpp | 277 | ||||
-rw-r--r-- | platform/x11/os_x11.h | 18 | ||||
-rw-r--r-- | platform/x11/vulkan_context_x11.cpp | 57 | ||||
-rw-r--r-- | platform/x11/vulkan_context_x11.h | 48 |
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 |