From 9a077da79c8122e1e255a8ef02d423db4da1e7d0 Mon Sep 17 00:00:00 2001 From: Martijn Courteaux Date: Fri, 4 Oct 2024 14:17:01 +0200 Subject: [PATCH] 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. --- examples/22-windows/windows.cpp | 15 ++++++ examples/common/entry/entry_glfw.cpp | 68 +++++++++++----------------- examples/common/entry/entry_p.h | 4 -- examples/common/entry/entry_sdl.cpp | 33 ++++---------- scripts/example-common.lua | 6 --- scripts/genie.lua | 18 -------- scripts/geometryv.lua | 22 --------- scripts/texturev.lua | 22 --------- src/glcontext_egl.cpp | 58 ++++++++++++++++++------ src/glcontext_egl.h | 14 +++--- src/glcontext_html5.cpp | 5 +- src/glcontext_html5.h | 2 +- src/glcontext_wgl.cpp | 3 +- src/glcontext_wgl.h | 2 +- src/renderer_gl.cpp | 2 +- src/renderer_vk.cpp | 43 +++++++++++++++--- src/renderer_vk.h | 26 +---------- 17 files changed, 147 insertions(+), 196 deletions(-) diff --git a/examples/22-windows/windows.cpp b/examples/22-windows/windows.cpp index 4c48185c8c5..f8c891e564b 100644 --- a/examples/22-windows/windows.cpp +++ b/examples/22-windows/windows.cpp @@ -204,6 +204,20 @@ class ExampleWindows : public entry::AppI 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 @@ class ExampleWindows : public entry::AppI 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/examples/common/entry/entry_glfw.cpp b/examples/common/entry/entry_glfw.cpp index 2a4d2771666..f667ef54716 100644 --- a/examples/common/entry/entry_glfw.cpp +++ b/examples/common/entry/entry_glfw.cpp @@ -15,13 +15,9 @@ #endif // GLFW_VERSION_MINOR < 2 #if BX_PLATFORM_LINUX -# 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,12 +41,13 @@ namespace entry static void* glfwNativeWindowHandle(GLFWwindow* _window) { # if BX_PLATFORM_LINUX -# if ENTRY_CONFIG_USE_WAYLAND - struct wl_surface* surface = (struct wl_surface*)glfwGetWaylandWindow(_window); - return (void*)surface; -# else - return (void*)(uintptr_t)glfwGetX11Window(_window); -# endif + if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND) + { + return glfwGetWaylandWindow(_window); + } else + { + return (void*)(uintptr_t)glfwGetX11Window(_window); + } # elif BX_PLATFORM_OSX return glfwGetCocoaWindow(_window); # elif BX_PLATFORM_WINDOWS @@ -58,23 +55,6 @@ namespace entry # endif // BX_PLATFORM_ } - static void glfwDestroyWindowImpl(GLFWwindow *_window) - { - if(!_window) - return; -# if BX_PLATFORM_LINUX -# 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; @@ -515,7 +495,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; } } @@ -607,7 +587,7 @@ namespace entry m_eventQueue.postExitEvent(); m_thread.shutdown(); - glfwDestroyWindowImpl(m_window[0]); + glfwDestroyWindow(m_window[0]); glfwTerminate(); return m_thread.getExitCode(); @@ -855,11 +835,13 @@ namespace entry void* getNativeDisplayHandle() { # if BX_PLATFORM_LINUX -# 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_* @@ -868,11 +850,13 @@ namespace entry bgfx::NativeWindowHandleType::Enum getNativeWindowHandleType() { # if BX_PLATFORM_LINUX -# 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/examples/common/entry/entry_p.h b/examples/common/entry/entry_p.h index 34444a639fc..1295f7a3923 100644 --- a/examples/common/entry/entry_p.h +++ b/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/examples/common/entry/entry_sdl.cpp b/examples/common/entry/entry_sdl.cpp index ed57ba73f3f..42cc8fb8795 100644 --- a/examples/common/entry/entry_sdl.cpp +++ b/examples/common/entry/entry_sdl.cpp @@ -46,12 +46,10 @@ namespace entry } # if BX_PLATFORM_LINUX -# if ENTRY_CONFIG_USE_WAYLAND - if (wmi.subsystem == SDL_SYSWM_WAYLAND) - return (void*)wmi.info.wl.surface; - 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 || BX_PLATFORM_VISIONOS return wmi.info.cocoa.window; # elif BX_PLATFORM_WINDOWS @@ -61,13 +59,6 @@ namespace entry # endif // BX_PLATFORM_ } - static void sdlDestroyWindow(SDL_Window* _window) - { - if(!_window) - return; - SDL_DestroyWindow(_window); - } - static uint8_t translateKeyModifiers(uint16_t _sdl) { uint8_t modifiers = 0; @@ -779,7 +770,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; } } @@ -873,7 +864,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(); @@ -1063,12 +1054,10 @@ namespace entry return NULL; } # if BX_PLATFORM_LINUX -# 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_* @@ -1083,13 +1072,11 @@ namespace entry return bgfx::NativeWindowHandleType::Default; } # if BX_PLATFORM_LINUX -# 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; } diff --git a/scripts/example-common.lua b/scripts/example-common.lua index 70c07579ee5..e635be076db 100644 --- a/scripts/example-common.lua +++ b/scripts/example-common.lua @@ -79,12 +79,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/scripts/genie.lua b/scripts/genie.lua index 1bbb57687f7..3624f66b589 100644 --- a/scripts/genie.lua +++ b/scripts/genie.lua @@ -20,11 +20,6 @@ newoption { description = "Enable GLFW entry.", } -newoption { - trigger = "with-wayland", - description = "Enable Wayland support.", -} - newoption { trigger = "with-profiler", description = "Enable build with intrusive profiler.", @@ -187,10 +182,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 @@ -245,15 +236,6 @@ function exampleProjectDefaults() 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/scripts/geometryv.lua b/scripts/geometryv.lua index a79a800eff5..511bf55f788 100644 --- a/scripts/geometryv.lua +++ b/scripts/geometryv.lua @@ -35,13 +35,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" } @@ -55,21 +48,6 @@ project ("geometryv") 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/scripts/texturev.lua b/scripts/texturev.lua index 0a34eef8b06..ac9e0be3b52 100644 --- a/scripts/texturev.lua +++ b/scripts/texturev.lua @@ -35,13 +35,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" } @@ -55,21 +48,6 @@ project "texturev" 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/src/glcontext_egl.cpp b/src/glcontext_egl.cpp index ec7e9043cb2..273c40b9686 100644 --- a/src/glcontext_egl.cpp +++ b/src/glcontext_egl.cpp @@ -124,7 +124,7 @@ EGL_IMPORT } #endif // BGFX_USE_GL_DYNAMIC_LIB -#if defined(WL_EGL_PLATFORM) +#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 *)) \ @@ -159,7 +159,7 @@ WL_EGL_IMPORT WL_EGL_IMPORT # undef WL_EGL_FUNC } -#endif // defined(WL_EGL_PLATFORM) +#endif // BX_PLATFORM_LINUX # define GL_IMPORT(_optional, _proto, _func, _import) _proto _func = NULL # include "glimports.h" @@ -168,18 +168,32 @@ WL_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); } @@ -207,6 +221,12 @@ WL_EGL_IMPORT EGL_CHECK(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ); EGL_CHECK(eglDestroyContext(m_display, m_context) ); EGL_CHECK(eglDestroySurface(m_display, m_surface) ); +# if BX_PLATFORM_LINUX + if (m_eglWindow) + { + BGFX_WAYLAND_wl_egl_window_destroy(m_eglWindow); + } +# endif EGL_CHECK(eglMakeCurrent(m_display, defaultSurface, defaultSurface, defaultContext) ); } @@ -224,6 +244,9 @@ WL_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 @@ -366,17 +389,12 @@ WL_EGL_IMPORT vc_dispmanx_update_submit_sync(dispmanUpdate); # endif // BX_PLATFORM_ANDROID -# if defined(WL_EGL_PLATFORM) +# if BX_PLATFORM_LINUX if (g_platformData.type == NativeWindowHandleType::Wayland) { m_waylandEglDll = waylandEglOpen(); - - // 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 = m_eglWindow; } -# endif // defined(WL_EGL_PLATFORM) +# endif if (headless) { @@ -392,6 +410,15 @@ WL_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); } @@ -474,20 +501,21 @@ WL_EGL_IMPORT void GlContext::destroy() { + BX_TRACE("GLContext::destroy()"); if (NULL != m_display) { EGL_CHECK(eglMakeCurrent(m_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) ); EGL_CHECK(eglDestroyContext(m_display, m_context) ); EGL_CHECK(eglDestroySurface(m_display, m_surface) ); -# if defined(WL_EGL_PLATFORM) +# if BX_PLATFORM_LINUX if (m_eglWindow) { BGFX_WAYLAND_wl_egl_window_destroy(m_eglWindow); waylandEglClose(m_waylandEglDll); m_waylandEglDll = NULL; } -# endif // defined(WL_EGL_PLATFORM) +# endif EGL_CHECK(eglTerminate(m_display) ); m_context = NULL; @@ -521,7 +549,7 @@ WL_EGL_IMPORT } # elif BX_PLATFORM_EMSCRIPTEN EMSCRIPTEN_CHECK(emscripten_set_canvas_element_size(HTML5_TARGET_CANVAS_SELECTOR, _width, _height) ); -# elif defined(WL_EGL_PLATFORM) +# elif BX_PLATFORM_LINUX if (NULL != m_eglWindow) { BGFX_WAYLAND_wl_egl_window_resize(m_eglWindow, _width, _height, 0, 0); @@ -549,9 +577,9 @@ WL_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/src/glcontext_egl.h b/src/glcontext_egl.h index 68f8e3db649..6848978f416 100644 --- a/src/glcontext_egl.h +++ b/src/glcontext_egl.h @@ -11,6 +11,7 @@ #include #include +struct wl_egl_window; // EGL pulls X11 crap... #if defined(None) @@ -32,14 +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 defined(WL_EGL_PLATFORM) +#if BX_PLATFORM_LINUX , m_waylandEglDll(NULL) , m_eglWindow(NULL) -#endif // defined(WL_EGL_PLATFORM) +#endif , m_msaaContext(false) { } @@ -49,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); @@ -68,10 +70,10 @@ namespace bgfx { namespace gl EGLDisplay m_display; EGLSurface m_surface; -#if defined(WL_EGL_PLATFORM) +#if BX_PLATFORM_LINUX void* m_waylandEglDll; struct wl_egl_window *m_eglWindow; -#endif // defined(WL_EGL_PLATFORM) +#endif // true when MSAA is handled by the context instead of using MSAA FBO bool m_msaaContext; diff --git a/src/glcontext_html5.cpp b/src/glcontext_html5.cpp index 6e89f4876e0..4956a795928 100644 --- a/src/glcontext_html5.cpp +++ b/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/src/glcontext_html5.h b/src/glcontext_html5.h index 77d215fde49..49757892d4b 100644 --- a/src/glcontext_html5.h +++ b/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/src/glcontext_wgl.cpp b/src/glcontext_wgl.cpp index 1dc08a35a70..cfa653a6766 100644 --- a/src/glcontext_wgl.cpp +++ b/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/src/glcontext_wgl.h b/src/glcontext_wgl.h index 259dfb829d4..abe943663b2 100644 --- a/src/glcontext_wgl.h +++ b/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/src/renderer_gl.cpp b/src/renderer_gl.cpp index c5b3648fb36..e8419f5a183 100644 --- a/src/renderer_gl.cpp +++ b/src/renderer_gl.cpp @@ -7151,7 +7151,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/src/renderer_vk.cpp b/src/renderer_vk.cpp index aeae00cc5ad..2e2e9b85286 100644 --- a/src/renderer_vk.cpp +++ b/src/renderer_vk.cpp @@ -362,6 +362,20 @@ VK_IMPORT_DEVICE KHR_draw_indirect_count, KHR_get_physical_device_properties2, +# 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, +# elif BX_PLATFORM_NX + NN_vi_surface, +# endif + Count }; @@ -386,6 +400,19 @@ VK_IMPORT_DEVICE { "VK_EXT_shader_viewport_index_layer", 1, false, false, true, Layer::Count }, { "VK_KHR_draw_indirect_count", 1, false, false, true, Layer::Count }, { "VK_KHR_get_physical_device_properties2", 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 }, +# elif BX_PLATFORM_NX + { VK_NN_VI_SURFACE_EXTENSION_NAME, 1, false, false, true, Layer::Count }, +# endif }; BX_STATIC_ASSERT(Extension::Count == BX_COUNTOF(s_extension) ); @@ -1178,7 +1205,7 @@ VK_IMPORT_DEVICE #else "libvulkan.so.1" #endif // BX_PLATFORM_* - ); + ); if (NULL == m_vulkan1Dll) { @@ -1244,12 +1271,11 @@ VK_IMPORT } uint32_t numEnabledExtensions = 0; - const char* enabledExtension[Extension::Count + 2]; + const char* enabledExtension[Extension::Count + 1]; if (!headless) { enabledExtension[numEnabledExtensions++] = VK_KHR_SURFACE_EXTENSION_NAME; - enabledExtension[numEnabledExtensions++] = KHR_SURFACE_EXTENSION_NAME; } for (uint32_t ii = 0; ii < Extension::Count; ++ii) @@ -6928,9 +6954,10 @@ 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"); VkWaylandSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6940,10 +6967,10 @@ VK_DESTROY 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") VkXlibSurfaceCreateInfoKHR sci; sci.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; sci.pNext = NULL; @@ -6953,7 +6980,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"); @@ -6965,6 +6992,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; diff --git a/src/renderer_vk.h b/src/renderer_vk.h index 6e47d855828..c47bd0d73c4 100644 --- a/src/renderer_vk.h +++ b/src/renderer_vk.h @@ -8,34 +8,22 @@ #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 -# 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 #elif BX_PLATFORM_NX # define VK_USE_PLATFORM_VI_NN -# define KHR_SURFACE_EXTENSION_NAME VK_NN_VI_SURFACE_EXTENSION_NAME # define VK_IMPORT_INSTANCE_PLATFORM VK_IMPORT_INSTANCE_NX #else -# define KHR_SURFACE_EXTENSION_NAME "" # define VK_IMPORT_INSTANCE_PLATFORM #endif // BX_PLATFORM_* @@ -73,7 +61,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); \ @@ -85,17 +72,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); \