From ba6f5853e9382a959af8ff81980c0f06a6ffe80e Mon Sep 17 00:00:00 2001 From: Julian Sikorski Date: Thu, 2 Jan 2025 13:50:37 +0100 Subject: [PATCH] Cherry-pick wayland improvements from upstream bgfx (#13070) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Properly support Wayland under EGL and Vulkan. (#3358) * Dynamically load libwayland-egl.so.1 when dealing with Wayland to remove dependencies at program startup. (#3359) * Cleanup. * Support both X11 and Wayland in the same build. (#3360) * Support both X11 and Wayland in the same build. - Works for both Vulkan and OpenGL. - Remove --with-wayland from genie options. - Vulkan loads all three extensions for surface creation instead of only one. - Add width and height parameter to GlContext::createSwapChain(), which is needed for EGL to create a SwapChain with the given window size. - Dirty-fix the example-22-windows to recreate the FrameBuffer by first destroying and then recreating to make sure the window is released of its swapchain. - Fix dbgText glitch in example-22-windows. - Remove old X11-related dependencies for GLFW3. * Formatting. * Adapt to latest bgfx wayland code * Cleanup. * Fix Vulkan swapchain invalidation issue. (#3379) * Fix Vulkan swapchain invalidation issue. * Always clamp render pass to frame buffer size. * Fix formatting. * Hopefully fix macOS build * Hopefully fix macOS build, attempt 2 --------- Co-authored-by: Martijn Courteaux Co-authored-by: Бранимир Караџић --- 3rdparty/bgfx/examples/22-windows/windows.cpp | 15 ++ .../bgfx/examples/42-bunnylod/bunnylod.cpp | 10 +- 3rdparty/bgfx/examples/common/entry/entry.cpp | 3 + .../bgfx/examples/common/entry/entry_glfw.cpp | 77 ++++------ 3rdparty/bgfx/examples/common/entry/entry_p.h | 4 - .../bgfx/examples/common/entry/entry_sdl.cpp | 92 ++++-------- .../examples/common/entry/entry_windows.cpp | 8 +- .../bgfx/examples/common/example-glue.cpp | 2 + 3rdparty/bgfx/scripts/example-common.lua | 6 - 3rdparty/bgfx/scripts/genie.lua | 31 ---- 3rdparty/bgfx/scripts/geometryv.lua | 16 --- 3rdparty/bgfx/scripts/texturev.lua | 16 --- 3rdparty/bgfx/src/glcontext_egl.cpp | 102 ++++++++++++- 3rdparty/bgfx/src/glcontext_egl.h | 17 ++- 3rdparty/bgfx/src/glcontext_html5.cpp | 5 +- 3rdparty/bgfx/src/glcontext_html5.h | 2 +- 3rdparty/bgfx/src/glcontext_nsgl.h | 2 +- 3rdparty/bgfx/src/glcontext_nsgl.mm | 2 +- 3rdparty/bgfx/src/glcontext_wgl.cpp | 3 +- 3rdparty/bgfx/src/glcontext_wgl.h | 2 +- 3rdparty/bgfx/src/renderer_d3d11.cpp | 4 +- 3rdparty/bgfx/src/renderer_gl.cpp | 9 +- 3rdparty/bgfx/src/renderer_vk.cpp | 135 +++++++++++++----- 3rdparty/bgfx/src/renderer_vk.h | 28 +--- makefile | 5 - scripts/src/osd/sdl.lua | 15 -- scripts/src/osd/sdl_cfg.lua | 11 -- src/osd/modules/render/drawbgfx.cpp | 45 +----- 28 files changed, 321 insertions(+), 346 deletions(-) diff --git a/3rdparty/bgfx/examples/22-windows/windows.cpp b/3rdparty/bgfx/examples/22-windows/windows.cpp index 54d8671bf76..da1742079a1 100644 --- a/3rdparty/bgfx/examples/22-windows/windows.cpp +++ b/3rdparty/bgfx/examples/22-windows/windows.cpp @@ -204,6 +204,20 @@ public: m_fbh[viewId].idx = bgfx::kInvalidHandle; } + // Before we reattach a SwapChain to the window + // we must actually free up the previous one. + // The DestroyFrameBuffer command goes in the + // cmdPost CommandBuffer, which happens after + // the frame. The CreateFrameBuffer command goes + // int the cmdPre CommandBuffer, which happens + // at the beginning of the frame. Without this + // bgfx::frame() call, the creation would happen + // before it's destroyed, which would cause + // the platform window to have two SwapChains + // associated with it. + // Ideally, we have an operation of ResizeFrameBuffer. + bgfx::frame(); + win.m_nwh = m_state.m_nwh; win.m_width = m_state.m_width; win.m_height = m_state.m_height; @@ -276,6 +290,7 @@ public: int64_t now = bx::getHPCounter(); float time = (float)( (now-m_timeOffset)/double(bx::getHPFrequency() ) ); + bgfx::dbgTextClear(); if (NULL != m_bindings) { bgfx::dbgTextPrintf(0, 1, 0x2f, "Press 'c' to create or 'd' to destroy window."); diff --git a/3rdparty/bgfx/examples/42-bunnylod/bunnylod.cpp b/3rdparty/bgfx/examples/42-bunnylod/bunnylod.cpp index 67c276c2e3c..8330b8afcf6 100644 --- a/3rdparty/bgfx/examples/42-bunnylod/bunnylod.cpp +++ b/3rdparty/bgfx/examples/42-bunnylod/bunnylod.cpp @@ -68,11 +68,15 @@ public: static void remapIndices(uint32_t* _indices, uint32_t _num) { uint32_t target = 0; - for (uint32_t i = 0; i < _num; i++) { + for (uint32_t i = 0; i < _num; i++) + { uint32_t map = _indices[i]; - if (i != map) { + if (i != map) + { _indices[i] = _indices[map]; - } else { + } + else + { _indices[i] = target; ++target; } diff --git a/3rdparty/bgfx/examples/common/entry/entry.cpp b/3rdparty/bgfx/examples/common/entry/entry.cpp index 07621f3cd25..dc3e97488ea 100644 --- a/3rdparty/bgfx/examples/common/entry/entry.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry.cpp @@ -767,6 +767,7 @@ restart: handle = size->m_handle; _width = size->m_width; _height = size->m_height; + BX_TRACE("Window resize event: %d: %dx%d", handle, _width, _height); needReset = true; } @@ -800,6 +801,7 @@ restart: && needReset) { _reset = s_reset; + BX_TRACE("bgfx::reset(%d, %d, 0x%x)", _width, _height, _reset) bgfx::reset(_width, _height, _reset); inputSetMouseResolution(uint16_t(_width), uint16_t(_height) ); } @@ -979,6 +981,7 @@ restart: if (needReset) { _reset = s_reset; + BX_TRACE("bgfx::reset(%d, %d, 0x%x)", s_window[0].m_width, s_window[0].m_height, _reset) bgfx::reset(s_window[0].m_width, s_window[0].m_height, _reset); inputSetMouseResolution(uint16_t(s_window[0].m_width), uint16_t(s_window[0].m_height) ); } diff --git a/3rdparty/bgfx/examples/common/entry/entry_glfw.cpp b/3rdparty/bgfx/examples/common/entry/entry_glfw.cpp index d27745d1390..4c699f23a5e 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_glfw.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry_glfw.cpp @@ -15,13 +15,9 @@ #endif // GLFW_VERSION_MINOR < 2 #if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND -# include -# define GLFW_EXPOSE_NATIVE_WAYLAND -# else -# define GLFW_EXPOSE_NATIVE_X11 -# define GLFW_EXPOSE_NATIVE_GLX -# endif +# define GLFW_EXPOSE_NATIVE_WAYLAND +# define GLFW_EXPOSE_NATIVE_X11 +# define GLFW_EXPOSE_NATIVE_GLX #elif BX_PLATFORM_OSX # define GLFW_EXPOSE_NATIVE_COCOA # define GLFW_EXPOSE_NATIVE_NSGL @@ -45,22 +41,14 @@ namespace entry static void* glfwNativeWindowHandle(GLFWwindow* _window) { # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - wl_egl_window *win_impl = (wl_egl_window*)glfwGetWindowUserPointer(_window); - if(!win_impl) + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) { - int width, height; - glfwGetWindowSize(_window, &width, &height); - struct wl_surface* surface = (struct wl_surface*)glfwGetWaylandWindow(_window); - if(!surface) - return nullptr; - win_impl = wl_egl_window_create(surface, width, height); - glfwSetWindowUserPointer(_window, (void*)(uintptr_t)win_impl); + return glfwGetWaylandWindow(_window); + } + else + { + return (void*)(uintptr_t)glfwGetX11Window(_window); } - return (void*)(uintptr_t)win_impl; -# else - return (void*)(uintptr_t)glfwGetX11Window(_window); -# endif # elif BX_PLATFORM_OSX return glfwGetCocoaWindow(_window); # elif BX_PLATFORM_WINDOWS @@ -68,23 +56,6 @@ namespace entry # endif // BX_PLATFORM_ } - static void glfwDestroyWindowImpl(GLFWwindow *_window) - { - if(!_window) - return; -# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - wl_egl_window *win_impl = (wl_egl_window*)glfwGetWindowUserPointer(_window); - if(win_impl) - { - glfwSetWindowUserPointer(_window, nullptr); - wl_egl_window_destroy(win_impl); - } -# endif -# endif - glfwDestroyWindow(_window); - } - static uint8_t translateKeyModifiers(int _glfw) { uint8_t modifiers = 0; @@ -525,7 +496,7 @@ namespace entry { GLFWwindow* window = m_window[msg->m_handle.idx]; m_eventQueue.postWindowEvent(msg->m_handle); - glfwDestroyWindowImpl(window); + glfwDestroyWindow(window); m_window[msg->m_handle.idx] = NULL; } } @@ -617,7 +588,7 @@ namespace entry m_eventQueue.postExitEvent(); m_thread.shutdown(); - glfwDestroyWindowImpl(m_window[0]); + glfwDestroyWindow(m_window[0]); glfwTerminate(); return m_thread.getExitCode(); @@ -865,11 +836,14 @@ namespace entry void* getNativeDisplayHandle() { # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - return glfwGetWaylandDisplay(); -# else - return glfwGetX11Display(); -# endif // ENTRY_CONFIG_USE_WAYLAND + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) + { + return glfwGetWaylandDisplay(); + } + else + { + return glfwGetX11Display(); + } # else return NULL; # endif // BX_PLATFORM_* @@ -878,11 +852,14 @@ namespace entry bgfx::NativeWindowHandleType::Enum getNativeWindowHandleType(WindowHandle _handle) { # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - return bgfx::NativeWindowHandleType::Wayland; -# else - return bgfx::NativeWindowHandleType::Default; -# endif // ENTRY_CONFIG_USE_WAYLAND + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) + { + return bgfx::NativeWindowHandleType::Wayland; + } + else + { + return bgfx::NativeWindowHandleType::Default; + } # else return bgfx::NativeWindowHandleType::Default; # endif // BX_PLATFORM_* diff --git a/3rdparty/bgfx/examples/common/entry/entry_p.h b/3rdparty/bgfx/examples/common/entry/entry_p.h index 59307c2f040..3c01e3459c8 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_p.h +++ b/3rdparty/bgfx/examples/common/entry/entry_p.h @@ -25,10 +25,6 @@ # define ENTRY_CONFIG_USE_GLFW 0 #endif // ENTRY_CONFIG_USE_GLFW -#ifndef ENTRY_CONFIG_USE_WAYLAND -# define ENTRY_CONFIG_USE_WAYLAND 0 -#endif // ENTRY_CONFIG_USE_WAYLAND - #if !defined(ENTRY_CONFIG_USE_NATIVE) \ && !ENTRY_CONFIG_USE_NOOP \ && !ENTRY_CONFIG_USE_SDL \ diff --git a/3rdparty/bgfx/examples/common/entry/entry_sdl.cpp b/3rdparty/bgfx/examples/common/entry/entry_sdl.cpp index 5a862c0ca05..bbcdb069257 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_sdl.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry_sdl.cpp @@ -8,9 +8,6 @@ #if ENTRY_CONFIG_USE_SDL #if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND -# include -# endif #elif BX_PLATFORM_WINDOWS # define SDL_MAIN_HANDLED #endif @@ -49,25 +46,14 @@ namespace entry } # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - if (wmi.subsystem == SDL_SYSWM_WAYLAND) - { - wl_egl_window *win_impl = (wl_egl_window*)SDL_GetWindowData(_window, "wl_egl_window"); - if(!win_impl) - { - int width, height; - SDL_GetWindowSize(_window, &width, &height); - struct wl_surface* surface = wmi.info.wl.surface; - if(!surface) - return nullptr; - win_impl = wl_egl_window_create(surface, width, height); - SDL_SetWindowData(_window, "wl_egl_window", win_impl); - } - return (void*)(uintptr_t)win_impl; - } - else -# endif // ENTRY_CONFIG_USE_WAYLAND - return (void*)wmi.info.x11.window; + if (wmi.subsystem == SDL_SYSWM_WAYLAND) + { + return (void*)wmi.info.wl.surface; + } + else + { + return (void*)wmi.info.x11.window; + } # elif BX_PLATFORM_OSX || BX_PLATFORM_IOS return wmi.info.cocoa.window; # elif BX_PLATFORM_WINDOWS @@ -77,23 +63,6 @@ namespace entry # endif // BX_PLATFORM_ } - static void sdlDestroyWindow(SDL_Window* _window) - { - if(!_window) - return; -# if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - wl_egl_window *win_impl = (wl_egl_window*)SDL_GetWindowData(_window, "wl_egl_window"); - if(win_impl) - { - SDL_SetWindowData(_window, "wl_egl_window", nullptr); - wl_egl_window_destroy(win_impl); - } -# endif -# endif - SDL_DestroyWindow(_window); - } - static uint8_t translateKeyModifiers(uint16_t _sdl) { uint8_t modifiers = 0; @@ -493,7 +462,7 @@ namespace entry // Force window resolution... WindowHandle defaultWindow = { 0 }; - setWindowSize(defaultWindow, m_width, m_height, true); + entry::setWindowSize(defaultWindow, m_width, m_height); SDL_EventState(SDL_DROPFILE, SDL_ENABLE); @@ -671,7 +640,15 @@ namespace entry case SDL_WINDOWEVENT_SIZE_CHANGED: { WindowHandle handle = findHandle(wev.windowID); - setWindowSize(handle, wev.data1, wev.data2); + uint32_t width = wev.data1; + uint32_t height = wev.data2; + if (width != m_width + || height != m_height) + { + m_width = width; + m_height = height; + m_eventQueue.postSizeEvent(handle, m_width, m_height); + } } break; @@ -865,7 +842,7 @@ namespace entry if (isValid(handle) ) { m_eventQueue.postWindowEvent(handle); - sdlDestroyWindow(m_window[handle.idx]); + SDL_DestroyWindow(m_window[handle.idx]); m_window[handle.idx] = NULL; } } @@ -916,7 +893,7 @@ namespace entry Msg* msg = (Msg*)uev.data2; if (isValid(handle) ) { - setWindowSize(handle, msg->m_width, msg->m_height); + SDL_SetWindowSize(m_window[handle.idx], msg->m_width, msg->m_height); } delete msg; } @@ -959,7 +936,7 @@ namespace entry while (bgfx::RenderFrame::NoContext != bgfx::renderFrame() ) {}; m_thread.shutdown(); - sdlDestroyWindow(m_window[0]); + SDL_DestroyWindow(m_window[0]); SDL_Quit(); return m_thread.getExitCode(); @@ -988,20 +965,6 @@ namespace entry return invalid; } - void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height, bool _force = false) - { - if (_width != m_width - || _height != m_height - || _force) - { - m_width = _width; - m_height = _height; - - SDL_SetWindowSize(m_window[_handle.idx], m_width, m_height); - m_eventQueue.postSizeEvent(_handle, m_width, m_height); - } - } - GamepadHandle findGamepad(SDL_JoystickID _jid) { for (uint32_t ii = 0, num = m_gamepadAlloc.getNumHandles(); ii < num; ++ii) @@ -1102,6 +1065,7 @@ namespace entry void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height) { + // Function to set the window size programmatically from the examples/tools. Msg* msg = new Msg; msg->m_width = _width; msg->m_height = _height; @@ -1149,12 +1113,10 @@ namespace entry return NULL; } # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND - if (wmi.subsystem == SDL_SYSWM_WAYLAND) - return wmi.info.wl.display; - else -# endif // ENTRY_CONFIG_USE_WAYLAND - return wmi.info.x11.display; + if (wmi.subsystem == SDL_SYSWM_WAYLAND) + return wmi.info.wl.display; + else + return wmi.info.x11.display; # else return NULL; # endif // BX_PLATFORM_* @@ -1169,11 +1131,9 @@ namespace entry return bgfx::NativeWindowHandleType::Default; } # if BX_PLATFORM_LINUX || BX_PLATFORM_BSD -# if ENTRY_CONFIG_USE_WAYLAND if (wmi.subsystem == SDL_SYSWM_WAYLAND) return bgfx::NativeWindowHandleType::Wayland; else -# endif // ENTRY_CONFIG_USE_WAYLAND return bgfx::NativeWindowHandleType::Default; # else return bgfx::NativeWindowHandleType::Default; diff --git a/3rdparty/bgfx/examples/common/entry/entry_windows.cpp b/3rdparty/bgfx/examples/common/entry/entry_windows.cpp index 754039a6db7..e731977737e 100644 --- a/3rdparty/bgfx/examples/common/entry/entry_windows.cpp +++ b/3rdparty/bgfx/examples/common/entry/entry_windows.cpp @@ -851,14 +851,18 @@ namespace entry if (utf16[0] >= 0xD800 && utf16[0] <= 0xDBFF) { m_surrogate = utf16[0]; - } else { + } + else + { int utf16_len; if (utf16[0] >= 0xDC00 && utf16[0] <= 0xDFFF) { utf16[1] = utf16[0]; utf16[0] = m_surrogate; m_surrogate = 0; utf16_len = 2; - } else { + } + else + { utf16_len = 1; } diff --git a/3rdparty/bgfx/examples/common/example-glue.cpp b/3rdparty/bgfx/examples/common/example-glue.cpp index 74ff3719f18..3c51db6ee0f 100644 --- a/3rdparty/bgfx/examples/common/example-glue.cpp +++ b/3rdparty/bgfx/examples/common/example-glue.cpp @@ -290,6 +290,8 @@ void showExampleDialog(entry::AppI* _app, const char* _errorText) } } } +#else + ImGui::Text("Renderer: %s", bgfx::getRendererName(bgfx::getRendererType())); #endif // 0 const bgfx::Stats* stats = bgfx::getStats(); diff --git a/3rdparty/bgfx/scripts/example-common.lua b/3rdparty/bgfx/scripts/example-common.lua index c6ddb81fd6c..6dbddd670ec 100644 --- a/3rdparty/bgfx/scripts/example-common.lua +++ b/3rdparty/bgfx/scripts/example-common.lua @@ -75,12 +75,6 @@ project ("example-common") } end - if _OPTIONS["with-wayland"] then - defines { - "ENTRY_CONFIG_USE_WAYLAND=1", - } - end - configuration { "android-*" } includedirs { path.join(BGFX_DIR, "3rdparty/native_app_glue") diff --git a/3rdparty/bgfx/scripts/genie.lua b/3rdparty/bgfx/scripts/genie.lua index 645ed3a21be..d3f4047cd93 100644 --- a/3rdparty/bgfx/scripts/genie.lua +++ b/3rdparty/bgfx/scripts/genie.lua @@ -20,11 +20,6 @@ newoption { description = "Enable GLFW entry.", } -newoption { - trigger = "with-wayland", - description = "Use Wayland backend.", -} - newoption { trigger = "with-profiler", description = "Enable build with intrusive profiler.", @@ -204,10 +199,6 @@ end function copyLib() end -if _OPTIONS["with-wayland"] then - defines { "WL_EGL_PLATFORM=1" } -end - if _OPTIONS["with-sdl"] then if os.is("windows") then if not os.getenv("SDL2_DIR") then @@ -256,13 +247,6 @@ function exampleProjectDefaults() defines { "ENTRY_CONFIG_USE_SDL=1" } links { "SDL2" } - configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - end - configuration { "osx*" } libdirs { "$(SDL2_DIR)/lib" } @@ -273,21 +257,6 @@ function exampleProjectDefaults() defines { "ENTRY_CONFIG_USE_GLFW=1" } links { "glfw3" } - configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - else - links { - "Xrandr", - "Xinerama", - "Xi", - "Xxf86vm", - "Xcursor", - } - end - configuration { "osx*" } linkoptions { "-framework CoreVideo", diff --git a/3rdparty/bgfx/scripts/geometryv.lua b/3rdparty/bgfx/scripts/geometryv.lua index e403d582179..054daf7af0d 100644 --- a/3rdparty/bgfx/scripts/geometryv.lua +++ b/3rdparty/bgfx/scripts/geometryv.lua @@ -30,13 +30,6 @@ project ("geometryv") defines { "ENTRY_CONFIG_USE_SDL=1" } links { "SDL2" } - configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - end - configuration { "x32", "windows" } libdirs { "$(SDL2_DIR)/lib/x86" } @@ -50,15 +43,6 @@ project ("geometryv") defines { "ENTRY_CONFIG_USE_GLFW=1" } links { "glfw3" } - configuration { "linux or freebsd" } - links { - "Xrandr", - "Xinerama", - "Xi", - "Xxf86vm", - "Xcursor", - } - configuration { "osx*" } linkoptions { "-framework CoreVideo", diff --git a/3rdparty/bgfx/scripts/texturev.lua b/3rdparty/bgfx/scripts/texturev.lua index d5bb9e2f08a..80f7dc4e814 100644 --- a/3rdparty/bgfx/scripts/texturev.lua +++ b/3rdparty/bgfx/scripts/texturev.lua @@ -30,13 +30,6 @@ project ("texturev") defines { "ENTRY_CONFIG_USE_SDL=1" } links { "SDL2" } - configuration { "linux or freebsd" } - if _OPTIONS["with-wayland"] then - links { - "wayland-egl", - } - end - configuration { "x32", "windows" } libdirs { "$(SDL2_DIR)/lib/x86" } @@ -50,15 +43,6 @@ project ("texturev") defines { "ENTRY_CONFIG_USE_GLFW=1" } links { "glfw3" } - configuration { "linux or freebsd" } - links { - "Xrandr", - "Xinerama", - "Xi", - "Xxf86vm", - "Xcursor", - } - configuration { "osx*" } linkoptions { "-framework CoreVideo", diff --git a/3rdparty/bgfx/src/glcontext_egl.cpp b/3rdparty/bgfx/src/glcontext_egl.cpp index 54e0230b778..85de92e1df5 100644 --- a/3rdparty/bgfx/src/glcontext_egl.cpp +++ b/3rdparty/bgfx/src/glcontext_egl.cpp @@ -111,6 +111,43 @@ EGL_IMPORT } #endif // BGFX_USE_GL_DYNAMIC_LIB + +#if BX_PLATFORM_LINUX +# define WL_EGL_IMPORT \ + WL_EGL_FUNC(struct wl_egl_window *, wl_egl_window_create, (struct wl_surface *, int, int) ) \ + WL_EGL_FUNC(void, wl_egl_window_destroy, (struct wl_egl_window *)) \ + WL_EGL_FUNC(void, wl_egl_window_resize, (struct wl_egl_window *, int, int, int, int)) \ + WL_EGL_FUNC(void, wl_egl_window_get_attached_size, (struct wl_egl_window *, int *, int *) ) \ + +# define WL_EGL_FUNC(rt, fname, params) \ + typedef rt(*PFNWLEGL_##fname) params; \ + PFNWLEGL_##fname BGFX_WAYLAND_##fname; + +WL_EGL_IMPORT +# undef WL_EGL_FUNC + + void* waylandEglOpen() + { + void* handle = bx::dlopen("libwayland-egl.so.1"); + BGFX_FATAL(handle != NULL, Fatal::UnableToInitialize, "Could not dlopen() libwayland-egl.so.1"); + +# define WL_EGL_FUNC(rt, fname, params) BGFX_WAYLAND_##fname = (PFNWLEGL_##fname) bx::dlsym(handle, #fname); + WL_EGL_IMPORT +# undef WL_EGL_FUNC + + return handle; + } + + void waylandEglClose(void* _handle) + { + bx::dlclose(_handle); + +# define WL_EGL_FUNC(rt, fname, params) BGFX_WAYLAND_##fname = NULL; + WL_EGL_IMPORT +# undef WL_EGL_FUNC + } +#endif // BX_PLATFORM_LINUX + # define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL # include "glimports.h" @@ -118,18 +155,32 @@ EGL_IMPORT struct SwapChainGL { - SwapChainGL(EGLDisplay _display, EGLConfig _config, EGLContext _context, EGLNativeWindowType _nwh) + SwapChainGL(EGLDisplay _display, EGLConfig _config, EGLContext _context, EGLNativeWindowType _nwh, int _width, int _height) : m_nwh(_nwh) , m_display(_display) +# if BX_PLATFORM_LINUX + , m_eglWindow(NULL) +# endif { EGLSurface defaultSurface = eglGetCurrentSurface(EGL_DRAW); + BX_UNUSED(_width, _height); + if (EGLNativeWindowType(0) == _nwh) { m_surface = eglCreatePbufferSurface(m_display, _config, NULL); } else { +# if BX_PLATFORM_LINUX + if (g_platformData.type == NativeWindowHandleType::Wayland) + { + // A wl_surface needs to be first wrapped in a wl_egl_window + // before it can be used to create the EGLSurface. + m_eglWindow = BGFX_WAYLAND_wl_egl_window_create( (wl_surface*)_nwh, _width, _height); + _nwh = (EGLNativeWindowType) m_eglWindow; + } +# endif m_surface = eglCreateWindowSurface(m_display, _config, _nwh, NULL); } @@ -157,6 +208,12 @@ EGL_IMPORT eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_display, m_context); eglDestroySurface(m_display, m_surface); +# if BX_PLATFORM_LINUX + if (m_eglWindow) + { + BGFX_WAYLAND_wl_egl_window_destroy(m_eglWindow); + } +# endif eglMakeCurrent(m_display, defaultSurface, defaultSurface, defaultContext); } @@ -174,6 +231,9 @@ EGL_IMPORT EGLContext m_context; EGLDisplay m_display; EGLSurface m_surface; +# if BX_PLATFORM_LINUX + wl_egl_window *m_eglWindow; +# endif }; # if BX_PLATFORM_RPI @@ -188,7 +248,7 @@ EGL_IMPORT bcm_host_init(); # endif // BX_PLATFORM_RPI - m_eglLibrary = eglOpen(); + m_eglDll = eglOpen(); if (NULL == g_platformData.context) { @@ -207,7 +267,7 @@ EGL_IMPORT } # endif // BX_PLATFORM_WINDOWS - m_display = eglGetDisplay(NULL == ndt ? EGL_DEFAULT_DISPLAY : ndt); + m_display = eglGetDisplay(NULL == ndt ? EGL_DEFAULT_DISPLAY : ndt); BGFX_FATAL(m_display != EGL_NO_DISPLAY, Fatal::UnableToInitialize, "Failed to create display %p", m_display); EGLint major = 0; @@ -316,6 +376,12 @@ EGL_IMPORT vc_dispmanx_update_submit_sync(dispmanUpdate); # endif // BX_PLATFORM_ANDROID +# if BX_PLATFORM_LINUX + if (g_platformData.type == NativeWindowHandleType::Wayland) + { + m_waylandEglDll = waylandEglOpen(); + } +# endif if (headless) { EGLint pbAttribs[] = @@ -330,6 +396,15 @@ EGL_IMPORT } else { +# if BX_PLATFORM_LINUX + if (g_platformData.type == NativeWindowHandleType::Wayland) + { + // A wl_surface needs to be first wrapped in a wl_egl_window + // before it can be used to create the EGLSurface. + m_eglWindow = BGFX_WAYLAND_wl_egl_window_create( (wl_surface*)nwh, _width, _height); + nwh = (EGLNativeWindowType) m_eglWindow; + } +# endif m_surface = eglCreateWindowSurface(m_display, m_config, nwh, NULL); } @@ -412,16 +487,26 @@ EGL_IMPORT void GlContext::destroy() { + BX_TRACE("GLContext::destroy()"); if (NULL != m_display) { eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); eglDestroyContext(m_display, m_context); eglDestroySurface(m_display, m_surface); +# if BX_PLATFORM_LINUX + if (m_eglWindow) + { + BGFX_WAYLAND_wl_egl_window_destroy(m_eglWindow); + waylandEglClose(m_waylandEglDll); + m_waylandEglDll = NULL; + } +# endif eglTerminate(m_display); m_context = NULL; } - eglClose(m_eglLibrary); + eglClose(m_eglDll); + m_eglDll = NULL; # if BX_PLATFORM_RPI bcm_host_deinit(); @@ -447,6 +532,11 @@ EGL_IMPORT } # elif BX_PLATFORM_EMSCRIPTEN EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(HTML5_TARGET_CANVAS_SELECTOR, _width, _height) ); +# elif BX_PLATFORM_LINUX + if (NULL != m_eglWindow) + { + BGFX_WAYLAND_wl_egl_window_resize(m_eglWindow, _width, _height, 0, 0); + } # else BX_UNUSED(_width, _height); # endif // BX_PLATFORM_* @@ -470,9 +560,9 @@ EGL_IMPORT ; } - SwapChainGL* GlContext::createSwapChain(void* _nwh) + SwapChainGL* GlContext::createSwapChain(void* _nwh, int _width, int _height) { - return BX_NEW(g_allocator, SwapChainGL)(m_display, m_config, m_context, (EGLNativeWindowType)_nwh); + return BX_NEW(g_allocator, SwapChainGL)(m_display, m_config, m_context, (EGLNativeWindowType)_nwh, _width, _height); } void GlContext::destroySwapChain(SwapChainGL* _swapChain) diff --git a/3rdparty/bgfx/src/glcontext_egl.h b/3rdparty/bgfx/src/glcontext_egl.h index 2f87a32e5eb..28e7a5d49fb 100644 --- a/3rdparty/bgfx/src/glcontext_egl.h +++ b/3rdparty/bgfx/src/glcontext_egl.h @@ -11,6 +11,8 @@ #include #include +struct wl_egl_window; + // EGL pulls X11 crap... #if defined(None) # undef None @@ -31,10 +33,15 @@ namespace bgfx { namespace gl struct GlContext { GlContext() - : m_current(NULL) + : m_eglDll(NULL) + , m_current(NULL) , m_context(NULL) , m_display(NULL) , m_surface(NULL) +#if BX_PLATFORM_LINUX + , m_waylandEglDll(NULL) + , m_eglWindow(NULL) +#endif , m_msaaContext(false) { } @@ -44,7 +51,7 @@ namespace bgfx { namespace gl void resize(uint32_t _width, uint32_t _height, uint32_t _flags); uint64_t getCaps() const; - SwapChainGL* createSwapChain(void* _nwh); + SwapChainGL* createSwapChain(void* _nwh, int _w, int _h); void destroySwapChain(SwapChainGL* _swapChain); void swap(SwapChainGL* _swapChain = NULL); void makeCurrent(SwapChainGL* _swapChain = NULL); @@ -56,12 +63,16 @@ namespace bgfx { namespace gl return NULL != m_context; } - void* m_eglLibrary; + void* m_eglDll; SwapChainGL* m_current; EGLConfig m_config; EGLContext m_context; EGLDisplay m_display; EGLSurface m_surface; +#if BX_PLATFORM_LINUX + void* m_waylandEglDll; + struct wl_egl_window *m_eglWindow; +#endif // true when MSAA is handled by the context instead of using MSAA FBO bool m_msaaContext; }; diff --git a/3rdparty/bgfx/src/glcontext_html5.cpp b/3rdparty/bgfx/src/glcontext_html5.cpp index 016b7c189b3..0e55b792deb 100644 --- a/3rdparty/bgfx/src/glcontext_html5.cpp +++ b/3rdparty/bgfx/src/glcontext_html5.cpp @@ -86,7 +86,7 @@ namespace bgfx { namespace gl } else { - m_primary = createSwapChain((void*)canvas); + m_primary = createSwapChain((void*)canvas, (int)_width, (int)_height) ); } if (0 != _width @@ -122,9 +122,10 @@ namespace bgfx { namespace gl EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(m_primary->m_canvas, (int) _width, (int) _height) ); } - SwapChainGL* GlContext::createSwapChain(void* _nwh) + SwapChainGL* GlContext::createSwapChain(void* _nwh, int _width, int _height) { emscripten_webgl_init_context_attributes(&s_attrs); + BX_UNUSED(_width, _height); // Work around bug https://bugs.chromium.org/p/chromium/issues/detail?id=1045643 in Chrome // by having alpha always enabled. diff --git a/3rdparty/bgfx/src/glcontext_html5.h b/3rdparty/bgfx/src/glcontext_html5.h index 3c3f457d3c6..e1b93799a75 100644 --- a/3rdparty/bgfx/src/glcontext_html5.h +++ b/3rdparty/bgfx/src/glcontext_html5.h @@ -26,7 +26,7 @@ namespace bgfx { namespace gl void resize(uint32_t _width, uint32_t _height, uint32_t _flags); uint64_t getCaps() const; - SwapChainGL* createSwapChain(void* _nwh); + SwapChainGL* createSwapChain(void* _nwh, int _width, int _height); void destroySwapChain(SwapChainGL* _swapChain); void swap(SwapChainGL* _swapChain = NULL); void makeCurrent(SwapChainGL* _swapChain = NULL); diff --git a/3rdparty/bgfx/src/glcontext_nsgl.h b/3rdparty/bgfx/src/glcontext_nsgl.h index 560808b0fd5..ed331871e35 100644 --- a/3rdparty/bgfx/src/glcontext_nsgl.h +++ b/3rdparty/bgfx/src/glcontext_nsgl.h @@ -26,7 +26,7 @@ namespace bgfx { namespace gl void resize(uint32_t _width, uint32_t _height, uint32_t _flags); uint64_t getCaps() const; - SwapChainGL* createSwapChain(void* _nwh); + SwapChainGL* createSwapChain(void* _nwh, int _width, int _height); void destroySwapChain(SwapChainGL* _swapChain); void swap(SwapChainGL* _swapChain = NULL); void makeCurrent(SwapChainGL* _swapChain = NULL); diff --git a/3rdparty/bgfx/src/glcontext_nsgl.mm b/3rdparty/bgfx/src/glcontext_nsgl.mm index acb1900762c..93dd421205f 100644 --- a/3rdparty/bgfx/src/glcontext_nsgl.mm +++ b/3rdparty/bgfx/src/glcontext_nsgl.mm @@ -326,7 +326,7 @@ namespace bgfx { namespace gl return caps; } - SwapChainGL* GlContext::createSwapChain(void* _nwh) + SwapChainGL* GlContext::createSwapChain(void* _nwh, int _width, int _height) { return BX_NEW(g_allocator, SwapChainGL)(_nwh,(NSOpenGLContext*)m_context); } diff --git a/3rdparty/bgfx/src/glcontext_wgl.cpp b/3rdparty/bgfx/src/glcontext_wgl.cpp index f09a23d872e..efa0ec2080d 100644 --- a/3rdparty/bgfx/src/glcontext_wgl.cpp +++ b/3rdparty/bgfx/src/glcontext_wgl.cpp @@ -335,8 +335,9 @@ namespace bgfx { namespace gl return BGFX_CAPS_SWAP_CHAIN; } - SwapChainGL* GlContext::createSwapChain(void* _nwh) + SwapChainGL* GlContext::createSwapChain(void* _nwh, int _width, int _height) { + BX_UNUSED(_width, _height); SwapChainGL* swapChain = BX_NEW(g_allocator, SwapChainGL)(_nwh); int result = SetPixelFormat(swapChain->m_hdc, m_pixelFormat, &m_pfd); diff --git a/3rdparty/bgfx/src/glcontext_wgl.h b/3rdparty/bgfx/src/glcontext_wgl.h index 7289a123424..13b8d2ed880 100644 --- a/3rdparty/bgfx/src/glcontext_wgl.h +++ b/3rdparty/bgfx/src/glcontext_wgl.h @@ -74,7 +74,7 @@ typedef void (APIENTRYP PFNGLSTENCILOPPROC) (GLenum fail, GLenum zfail, GLenum z void resize(uint32_t _width, uint32_t _height, uint32_t _flags); uint64_t getCaps() const; - SwapChainGL* createSwapChain(void* _nwh); + SwapChainGL* createSwapChain(void* _nwh, int _width, int _height); void destroySwapChain(SwapChainGL* _swapChain); void swap(SwapChainGL* _swapChain = NULL); void makeCurrent(SwapChainGL* _swapChain = NULL); diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp index b15f0a12886..16095248be9 100644 --- a/3rdparty/bgfx/src/renderer_d3d11.cpp +++ b/3rdparty/bgfx/src/renderer_d3d11.cpp @@ -3396,10 +3396,10 @@ namespace bgfx { namespace d3d11 { case UniformType::Mat3: case UniformType::Mat3|kUniformFragmentBit: - { + { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) - { + { Matrix4 mtx; mtx.un.val[ 0] = value[0]; mtx.un.val[ 1] = value[1]; diff --git a/3rdparty/bgfx/src/renderer_gl.cpp b/3rdparty/bgfx/src/renderer_gl.cpp index 6fdf64225d7..ff860faec25 100644 --- a/3rdparty/bgfx/src/renderer_gl.cpp +++ b/3rdparty/bgfx/src/renderer_gl.cpp @@ -3046,7 +3046,8 @@ namespace bgfx { namespace gl } #if BGFX_CONFIG_RENDERER_OPENGLES && (BGFX_CONFIG_RENDERER_OPENGLES < 30) - if (!m_maxMsaa && s_extension[Extension::IMG_multisampled_render_to_texture].m_supported) { + if (!m_maxMsaa && s_extension[Extension::IMG_multisampled_render_to_texture].m_supported) + { GL_CHECK(glGetIntegerv(GL_MAX_SAMPLES_IMG, &m_maxMsaa) ); } #endif // BGFX_CONFIG_RENDERER_OPENGLES < 30 @@ -7112,7 +7113,9 @@ namespace bgfx { namespace gl { attachment = GL_DEPTH_ATTACHMENT; } - } else { + } + else + { attachment = GL_COLOR_ATTACHMENT0 + colorIdx; ++colorIdx; } @@ -7142,7 +7145,7 @@ namespace bgfx { namespace gl void FrameBufferGL::create(uint16_t _denseIdx, void* _nwh, uint32_t _width, uint32_t _height, TextureFormat::Enum _format, TextureFormat::Enum _depthFormat) { BX_UNUSED(_format, _depthFormat); - m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh); + m_swapChain = s_renderGL->m_glctx.createSwapChain(_nwh, _width, _height); m_width = _width; m_height = _height; m_numTh = 0; diff --git a/3rdparty/bgfx/src/renderer_vk.cpp b/3rdparty/bgfx/src/renderer_vk.cpp index aba25e78512..8b2c6cd001e 100644 --- a/3rdparty/bgfx/src/renderer_vk.cpp +++ b/3rdparty/bgfx/src/renderer_vk.cpp @@ -17,10 +17,6 @@ # import #endif // BX_PLATFORM_OSX -#if defined(WL_EGL_PLATFORM) -# include -#endif // defined(WL_EGL_PLATFORM) - namespace bgfx { namespace vk { static char s_viewName[BGFX_CONFIG_MAX_VIEWS][BGFX_CONFIG_MAX_VIEW_NAME]; @@ -346,6 +342,18 @@ VK_IMPORT_DEVICE EXT_shader_viewport_index_layer, EXT_custom_border_color, KHR_draw_indirect_count, + +# if BX_PLATFORM_ANDROID + KHR_android_surface, +# elif BX_PLATFORM_LINUX + KHR_wayland_surface, + KHR_xlib_surface, + KHR_xcb_surface, +# elif BX_PLATFORM_WINDOWS + KHR_win32_surface, +# elif BX_PLATFORM_OSX + MVK_macos_surface, +# endif Count }; @@ -371,6 +379,17 @@ VK_IMPORT_DEVICE { "VK_EXT_shader_viewport_index_layer", 1, false, false, true , Layer::Count }, { "VK_EXT_custom_border_color", 1, false, false, true , Layer::Count }, { "VK_KHR_draw_indirect_count", 1, false, false, true , Layer::Count }, +# if BX_PLATFORM_ANDROID + { VK_KHR_ANDROID_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_LINUX + { VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, + { VK_KHR_XLIB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, + { VK_KHR_XCB_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_WINDOWS + { VK_KHR_WIN32_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# elif BX_PLATFORM_OSX + { VK_MVK_MACOS_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# endif }; BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); @@ -1159,7 +1178,7 @@ VK_IMPORT_DEVICE #else "libvulkan.so.1" #endif // BX_PLATFORM_* - ); + ); if (NULL == m_vulkan1Dll) { @@ -1229,13 +1248,12 @@ VK_IMPORT const char* enabledExtension[Extension::Count + 3] = #else - uint32_t numEnabledExtensions = headless ? 0 : 2; + uint32_t numEnabledExtensions = headless ? 0 : 1; - const char* enabledExtension[Extension::Count + 2] = + const char* enabledExtension[Extension::Count + 1] = #endif { VK_KHR_SURFACE_EXTENSION_NAME, - KHR_SURFACE_EXTENSION_NAME, #if BX_PLATFORM_OSX VK_KHR_PORTABILITY_ENUMERATION_EXTENSION_NAME, #endif @@ -2664,6 +2682,7 @@ VK_IMPORT_DEVICE m_indexBuffers[_blitter.m_ib->handle.idx].update(m_commandBuffer, 0, _numIndices*2, _blitter.m_ib->data); m_vertexBuffers[_blitter.m_vb->handle.idx].update(m_commandBuffer, 0, numVertices*_blitter.m_layout.m_stride, _blitter.m_vb->data, true); + VkRenderPassBeginInfo rpbi; rpbi.sType = VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO; rpbi.pNext = NULL; @@ -2757,6 +2776,13 @@ VK_IMPORT_DEVICE { return suspended; } + + //BX_TRACE("updateResolution(%d, %d) m_resolution=(%d, %d)" + // , _resolution.width + // , _resolution.height + // , m_resolution.width + // , m_resolution.height + // ); uint32_t flags = _resolution.reset & ~(0 | BGFX_RESET_SUSPEND @@ -2764,19 +2790,13 @@ VK_IMPORT_DEVICE | BGFX_RESET_DEPTH_CLAMP ); - // Note: m_needToRefreshSwapchain is deliberately ignored when deciding whether to recreate the swapchain - // because it can happen several frames before submit is called with the new resolution. - // Instead, vkAcquireNextImageKHR and all draws to the backbuffer are skipped until the window size is updated. - // That also fixes a related issue where VK_ERROR_OUT_OF_DATE_KHR is returned from - // vkQueuePresentKHR when the window doesn't exist anymore, and vkGetPhysicalDeviceSurfaceCapabilitiesKHR - // fails with VK_ERROR_SURFACE_LOST_KHR. - if (false || m_resolution.format != _resolution.format || m_resolution.width != _resolution.width || m_resolution.height != _resolution.height || m_resolution.reset != flags - || m_backBuffer.m_swapChain.m_needToRecreateSurface) + || m_backBuffer.m_swapChain.m_needToRecreateSurface + || m_backBuffer.m_swapChain.m_needToRecreateSwapchain) { flags &= ~BGFX_RESET_INTERNAL_FORCE; @@ -2794,6 +2814,10 @@ VK_IMPORT_DEVICE preReset(); m_backBuffer.update(m_commandBuffer, m_resolution); + // Update the resolution again here, as the actual width and height + // is now final (as it was potentially clamped by the Vulkan driver). + m_resolution.width = m_backBuffer.m_width; + m_resolution.height = m_backBuffer.m_height; postReset(); } @@ -4131,10 +4155,10 @@ VK_IMPORT_DEVICE { case UniformType::Mat3: case UniformType::Mat3|kUniformFragmentBit: - { + { float* value = (float*)data; for (uint32_t ii = 0, count = num/3; ii < count; ++ii, loc += 3*16, value += 9) - { + { Matrix4 mtx; mtx.un.val[ 0] = value[0]; mtx.un.val[ 1] = value[1]; @@ -6658,6 +6682,7 @@ VK_DESTROY ; const bool recreateSwapchain = false + || m_needToRecreateSwapchain || m_resolution.format != _resolution.format || m_resolution.width != _resolution.width || m_resolution.height != _resolution.height @@ -6763,22 +6788,25 @@ VK_DESTROY } #elif BX_PLATFORM_LINUX { -#if defined(WL_EGL_PLATFORM) if (g_platformData.type == bgfx::NativeWindowHandleType::Wayland) { + BGFX_FATAL(s_extension[Extension::KHR_wayland_surface].m_supported, Fatal::UnableToInitialize, VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME " not supported"); + BGFX_FATAL(NULL != vkCreateWaylandSurfaceKHR, Fatal::UnableToInitialize, "vkCreateWaylandSurfaceKHR == 0"); + BX_TRACE("Attempting Wayland surface creation."); VkWaylandSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; sci.flags = 0; sci.display = (wl_display*)g_platformData.ndt; - sci.surface = (wl_surface*)((wl_egl_window*)m_nwh)->surface; + sci.surface = (wl_surface*)m_nwh; result = vkCreateWaylandSurfaceKHR(instance, &sci, allocatorCb, &m_surface); } else -#endif // defined(WL_EGL_PLATFORM) { - if (NULL != vkCreateXlibSurfaceKHR) + if (s_extension[Extension::KHR_xlib_surface].m_supported) { + BGFX_FATAL(NULL != vkCreateXlibSurfaceKHR, Fatal::UnableToInitialize, "vkCreateXlibSurfaceKHR == 0") + BX_TRACE("Attempting Xlib surface creation."); VkXlibSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6788,7 +6816,7 @@ VK_DESTROY result = vkCreateXlibSurfaceKHR(instance, &sci, allocatorCb, &m_surface); } - if (VK_SUCCESS != result) + if (VK_SUCCESS != result && s_extension[Extension::KHR_xcb_surface].m_supported) { void* xcbdll = bx::dlopen("libX11-xcb.so.1"); @@ -6800,6 +6828,8 @@ VK_DESTROY union { void* ptr; xcb_window_t window; } cast = { m_nwh }; + BGFX_FATAL(NULL != vkCreateXcbSurfaceKHR, Fatal::UnableToInitialize, "vkCreateXcbSurfaceKHR == 0") + VkXcbSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_XCB_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6932,6 +6962,15 @@ VK_DESTROY , surfaceCapabilities.minImageExtent.height , surfaceCapabilities.maxImageExtent.height ); + if (width != m_resolution.width || height != m_resolution.height) + { + BX_TRACE("Clamped swapchain resolution from %dx%d to %dx%d" + , m_resolution.width + , m_resolution.height + , width + , height + ); + } VkCompositeAlphaFlagBitsKHR compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; @@ -7052,6 +7091,8 @@ VK_DESTROY m_backBufferColorImageLayout[ii] = VK_IMAGE_LAYOUT_UNDEFINED; } + BX_TRACE("Succesfully created swapchain (%dx%d) with %d images.", width, height, m_numSwapChainImages); + VkSemaphoreCreateInfo sci; sci.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; sci.pNext = NULL; @@ -7071,7 +7112,7 @@ VK_DESTROY m_currentSemaphore = 0; m_needPresent = false; - m_needToRefreshSwapchain = false; + m_needToRecreateSwapchain = false; return result; } @@ -7373,7 +7414,7 @@ VK_DESTROY bool SwapChainVK::acquire(VkCommandBuffer _commandBuffer) { if (VK_NULL_HANDLE == m_swapchain - || m_needToRefreshSwapchain) + || m_needToRecreateSwapchain) { return false; } @@ -7395,6 +7436,11 @@ VK_DESTROY , &m_backBufferColorIdx ); + if (result != VK_SUCCESS) + { + BX_TRACE("vkAcquireNextImageKHR(...): result = %s", getName(result)); + } + switch (result) { case VK_SUCCESS: @@ -7402,11 +7448,12 @@ VK_DESTROY case VK_ERROR_SURFACE_LOST_KHR: m_needToRecreateSurface = true; - BX_FALLTHROUGH; + m_needToRecreateSwapchain = true; + return false; case VK_ERROR_OUT_OF_DATE_KHR: case VK_SUBOPTIMAL_KHR: - m_needToRefreshSwapchain = true; + m_needToRecreateSwapchain = true; return false; default: @@ -7448,16 +7495,22 @@ VK_DESTROY pi.pImageIndices = &m_backBufferColorIdx; pi.pResults = NULL; VkResult result = vkQueuePresentKHR(m_queue, &pi); + + if (result != VK_SUCCESS) + { + BX_TRACE("vkQueuePresentKHR(...): result = %s", getName(result)); + } switch (result) { case VK_ERROR_SURFACE_LOST_KHR: m_needToRecreateSurface = true; - BX_FALLTHROUGH; + m_needToRecreateSwapchain = true; + break; case VK_ERROR_OUT_OF_DATE_KHR: case VK_SUBOPTIMAL_KHR: - m_needToRefreshSwapchain = true; + m_needToRecreateSwapchain = true; break; default: @@ -7615,8 +7668,10 @@ VK_DESTROY { m_swapChain.update(_commandBuffer, m_nwh, _resolution); VK_CHECK(s_renderVK->getRenderPass(m_swapChain, &m_renderPass) ); - m_width = _resolution.width; - m_height = _resolution.height; + // Don't believe the passed Resolution, as the Vulkan driver might have + // specified another resolution, which we had to obey. + m_width = m_swapChain.m_sci.imageExtent.width; + m_height = m_swapChain.m_sci.imageExtent.height; m_sampler = m_swapChain.m_sampler; } @@ -8275,12 +8330,26 @@ VK_DESTROY if (isFrameBufferValid) { viewState.m_rect = _render->m_view[view].m_rect; - const Rect& rect = _render->m_view[view].m_rect; - const Rect& scissorRect = _render->m_view[view].m_scissor; + Rect rect = _render->m_view[view].m_rect; + Rect scissorRect = _render->m_view[view].m_scissor; viewHasScissor = !scissorRect.isZero(); viewScissorRect = viewHasScissor ? scissorRect : rect; restoreScissor = false; + // Clamp the rect to what's valid according to Vulkan. + rect.m_width = bx::min(rect.m_width, fb.m_width - rect.m_x); + rect.m_height = bx::min(rect.m_height, fb.m_height - rect.m_y); + if (_render->m_view[view].m_rect.m_width != rect.m_width + || _render->m_view[view].m_rect.m_height != rect.m_height) + { + BX_TRACE("Clamp render pass from %dx%d to %dx%d" + , _render->m_view[view].m_rect.m_width + , _render->m_view[view].m_rect.m_height + , rect.m_width + , rect.m_height + ); + } + rpbi.framebuffer = fb.m_currentFramebuffer; rpbi.renderPass = fb.m_renderPass; rpbi.renderArea.offset.x = rect.m_x; diff --git a/3rdparty/bgfx/src/renderer_vk.h b/3rdparty/bgfx/src/renderer_vk.h index fdd51301ea0..1852ed83123 100644 --- a/3rdparty/bgfx/src/renderer_vk.h +++ b/3rdparty/bgfx/src/renderer_vk.h @@ -8,31 +8,19 @@ #if BX_PLATFORM_ANDROID # define VK_USE_PLATFORM_ANDROID_KHR -# define KHR_SURFACE_EXTENSION_NAME VK_KHR_ANDROID_SURFACE_EXTENSION_NAME # define VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_ANDROID #elif BX_PLATFORM_LINUX -# if defined(WL_EGL_PLATFORM) -# define VK_USE_PLATFORM_WAYLAND_KHR -# endif // defined(WL_EGL_PLATFORM) +# define VK_USE_PLATFORM_WAYLAND_KHR # define VK_USE_PLATFORM_XLIB_KHR # define VK_USE_PLATFORM_XCB_KHR -# if defined(WL_EGL_PLATFORM) -# define KHR_SURFACE_EXTENSION_NAME VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME, \ - VK_KHR_XCB_SURFACE_EXTENSION_NAME -# else -# define KHR_SURFACE_EXTENSION_NAME VK_KHR_XCB_SURFACE_EXTENSION_NAME -# endif // defined(WL_EGL_PLATFORM) # define VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_LINUX #elif BX_PLATFORM_WINDOWS # define VK_USE_PLATFORM_WIN32_KHR -# define KHR_SURFACE_EXTENSION_NAME VK_KHR_WIN32_SURFACE_EXTENSION_NAME # define VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_WINDOWS #elif BX_PLATFORM_OSX # define VK_USE_PLATFORM_MACOS_MVK -# define KHR_SURFACE_EXTENSION_NAME VK_MVK_MACOS_SURFACE_EXTENSION_NAME # define VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_MACOS #else -# define KHR_SURFACE_EXTENSION_NAME "" # define VK_IMPORT_INSTANCE_PLATFORM #endif // BX_PLATFORM_* @@ -69,7 +57,6 @@ /* VK_KHR_android_surface */ \ VK_IMPORT_INSTANCE_FUNC(true, vkCreateAndroidSurfaceKHR); \ -#if defined(WL_EGL_PLATFORM) #define VK_IMPORT_INSTANCE_LINUX \ /* VK_KHR_wayland_surface */ \ VK_IMPORT_INSTANCE_FUNC(true, vkCreateWaylandSurfaceKHR); \ @@ -81,17 +68,6 @@ VK_IMPORT_INSTANCE_FUNC(true, vkCreateXcbSurfaceKHR); \ VK_IMPORT_INSTANCE_FUNC(true, vkGetPhysicalDeviceXcbPresentationSupportKHR); \ -#else -#define VK_IMPORT_INSTANCE_LINUX \ - /* VK_KHR_xlib_surface */ \ - VK_IMPORT_INSTANCE_FUNC(true, vkCreateXlibSurfaceKHR); \ - VK_IMPORT_INSTANCE_FUNC(true, vkGetPhysicalDeviceXlibPresentationSupportKHR); \ - /* VK_KHR_xcb_surface */ \ - VK_IMPORT_INSTANCE_FUNC(true, vkCreateXcbSurfaceKHR); \ - VK_IMPORT_INSTANCE_FUNC(true, vkGetPhysicalDeviceXcbPresentationSupportKHR); \ - -#endif // defined(WL_EGL_PLATFORM) - #define VK_IMPORT_INSTANCE_WINDOWS \ /* VK_KHR_win32_surface */ \ VK_IMPORT_INSTANCE_FUNC(true, vkCreateWin32SurfaceKHR); \ @@ -762,7 +738,7 @@ VK_DESTROY_FUNC(DescriptorSet); VkSemaphore m_lastImageAcquiredSemaphore; bool m_needPresent; - bool m_needToRefreshSwapchain; + bool m_needToRecreateSwapchain; bool m_needToRecreateSurface; TextureVK m_backBufferDepthStencil; diff --git a/makefile b/makefile index baad79bedba..c3ffd8c0721 100644 --- a/makefile +++ b/makefile @@ -38,7 +38,6 @@ # USE_PCAP = 1 # USE_QTDEBUG = 1 # NO_X11 = 1 -# USE_WAYLAND = 1 # NO_USE_XINPUT = 1 # NO_USE_XINPUT_WII_LIGHTGUN_HACK = 1 # FORCE_DRC_C_BACKEND = 1 @@ -807,10 +806,6 @@ ifdef MESA_INSTALL_ROOT PARAMS += --MESA_INSTALL_ROOT='$(MESA_INSTALL_ROOT)' endif -ifdef USE_WAYLAND -PARAMS += --USE_WAYLAND='$(USE_WAYLAND)' -endif - ifdef NO_X11 PARAMS += --NO_X11='$(NO_X11)' endif diff --git a/scripts/src/osd/sdl.lua b/scripts/src/osd/sdl.lua index cc31fa52008..3115c4d644f 100644 --- a/scripts/src/osd/sdl.lua +++ b/scripts/src/osd/sdl.lua @@ -37,12 +37,6 @@ function maintargetosdoptions(_target,_subtarget) end end - if _OPTIONS["USE_WAYLAND"]=="1" then - links { - "wayland-egl" - } - end - if _OPTIONS["NO_USE_XINPUT"]~="1" then links { "Xext", @@ -147,15 +141,6 @@ if not _OPTIONS["NO_X11"] then end end -newoption { - trigger = "USE_WAYLAND", - description = "Use Wayland", - allowed = { - { "0", "Do not use Wayland (use XWayland or X11)" }, - { "1", "Use Wayland" }, - }, -} - newoption { trigger = "NO_USE_XINPUT", description = "Disable use of Xinput", diff --git a/scripts/src/osd/sdl_cfg.lua b/scripts/src/osd/sdl_cfg.lua index 10dde2d511e..f3a970c4ad4 100644 --- a/scripts/src/osd/sdl_cfg.lua +++ b/scripts/src/osd/sdl_cfg.lua @@ -50,17 +50,6 @@ else } end -if _OPTIONS["USE_WAYLAND"]=="1" then - defines { - "SDLMAME_USE_WAYLAND", - } - if _OPTIONS["targetos"]=="linux" then - buildoptions { - backtick(pkgconfigcmd() .. " --cflags wayland-egl"), - } - end -end - if _OPTIONS["NO_USE_XINPUT"]=="1" then defines { "USE_XINPUT=0", diff --git a/src/osd/modules/render/drawbgfx.cpp b/src/osd/modules/render/drawbgfx.cpp index 36758914961..5fbb697089f 100644 --- a/src/osd/modules/render/drawbgfx.cpp +++ b/src/osd/modules/render/drawbgfx.cpp @@ -56,10 +56,6 @@ extern void *GetOSWindow(void *wincontroller); #endif #endif -#if defined(SDLMAME_USE_WAYLAND) -#include -#endif - #include #include @@ -386,36 +382,6 @@ bool video_bgfx::init_bgfx_library(osd_window &window) } -//============================================================ -// Helper for creating a wayland window -//============================================================ - -#if defined(SDLMAME_USE_WAYLAND) -wl_egl_window *create_wl_egl_window(SDL_Window *window, struct wl_surface *surface) -{ - if (!surface) - { - osd_printf_error("Wayland surface missing, aborting\n"); - return nullptr; - } - wl_egl_window *win_impl = (wl_egl_window *)SDL_GetWindowData(window, "wl_egl_window"); - if (!win_impl) - { - int width, height; - SDL_GetWindowSize(window, &width, &height); - win_impl = wl_egl_window_create(surface, width, height); - if (!win_impl) - { - osd_printf_error("Creating wayland window failed\n"); - return nullptr; - } - SDL_SetWindowData(window, "wl_egl_window", win_impl); - } - return win_impl; -} -#endif - - //============================================================ // Utility for setting up window handle //============================================================ @@ -457,10 +423,10 @@ bool video_bgfx::set_platform_data(bgfx::PlatformData &platform_data, osd_window platform_data.nwh = wmi.info.cocoa.window; break; #endif -#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) && defined(SDLMAME_USE_WAYLAND) +#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) case SDL_SYSWM_WAYLAND: platform_data.ndt = wmi.info.wl.display; - platform_data.nwh = create_wl_egl_window(dynamic_cast(window).platform_window(), wmi.info.wl.surface); + platform_data.nwh = wmi.info.wl.surface; if (!platform_data.nwh) { osd_printf_error("BGFX: Error creating a Wayland window\n"); @@ -553,12 +519,9 @@ static std::pair sdlNativeWindowHandle(SDL_Window *window) case SDL_SYSWM_COCOA: return std::make_pair(wmi.info.cocoa.window, true); #endif -#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) && defined(SDLMAME_USE_WAYLAND) +#if defined(SDL_VIDEO_DRIVER_WAYLAND) && SDL_VERSION_ATLEAST(2, 0, 16) case SDL_SYSWM_WAYLAND: - { - void *const platform_window = osd::create_wl_egl_window(window, wmi.info.wl.surface); - return std::make_pair(platform_window, platform_window != nullptr); - } + return std::make_pair(wmi.info.wl.surface, true); #endif #if defined(SDL_VIDEO_DRIVER_ANDROID) case SDL_SYSWM_ANDROID: