Skip to content

Commit

Permalink
Vulkan: add Wayland support
Browse files Browse the repository at this point in the history
  • Loading branch information
paroj committed Aug 11, 2024
1 parent bf585ac commit aab0c6a
Show file tree
Hide file tree
Showing 10 changed files with 64 additions and 36 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,5 +112,5 @@ jobs:
- uses: actions/checkout@v4
- name: Build
run: |
cmake -Bbuild -DOGRE_BUILD_DEPENDENCIES=OFF -DSWIG_EXECUTABLE=none -DOGRE_CONFIG_DOUBLE=ON -DOGRE_ASSERT_MODE=1 -DOGRE_PROFILING=ON -DOGRE_GLSUPPORT_USE_WAYLAND=ON .
cmake -Bbuild -DOGRE_BUILD_DEPENDENCIES=OFF -DSWIG_EXECUTABLE=none -DOGRE_CONFIG_DOUBLE=ON -DOGRE_ASSERT_MODE=1 -DOGRE_PROFILING=ON -DOGRE_USE_WAYLAND=ON .
cmake --build build -- -j 4
3 changes: 2 additions & 1 deletion BuildingOgre.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ particular component/ plugin from being built
- `OGRE_ASSERT_MODE` allows you to to disable all runtime assertion exceptions or turn them into calls to `std::abort`.
- `OGRE_RESOURCEMANGER_STRICT` allows you to turn on resource lookup related quirks for pre ogre 1.10 compatibility.
- `OGRE_NODELESS_POSITIONING` allows to use Lights and Cameras without attaching them to nodes (only for legacy code).
- `OGRE_GLSUPPORT_USE_WAYLAND` will use Wayland window system instead of X11 on Linux for GL-based RenderSystems.
- `OGRE_GLSUPPORT_USE_EGL` use EGL instead of GLX/ WGL for GL RenderSystems. This is required for Wayland support.
- `OGRE_USE_WAYLAND` will use Wayland window system instead of X11 on Linux.

Once you are satisfied, hit
*Configure* again and then click on *Generate*. CMake will then create
Expand Down
12 changes: 6 additions & 6 deletions Components/Bites/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ elseif(ANDROID)
endif()

cmake_dependent_option(OGRE_BITES_NATIVE_DIALOG "Provide a platform specific ConfigDialog implementation"
ON "NOT OGRE_GLSUPPORT_USE_WAYLAND;NOT ANDROID;NOT EMSCRIPTEN;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE;NOT UNIX OR APPLE OR XAW_LIBRARY" OFF)
ON "NOT OGRE_USE_WAYLAND;NOT ANDROID;NOT EMSCRIPTEN;NOT APPLE_IOS;NOT WINDOWS_STORE;NOT WINDOWS_PHONE;NOT UNIX OR APPLE OR XAW_LIBRARY" OFF)

if(NOT OGRE_BITES_NATIVE_DIALOG)
set_source_files_properties(src/OgreBitesConfigDialog.cpp PROPERTIES COMPILE_DEFINITIONS DISABLE_NATIVE_DIALOG)
Expand All @@ -134,13 +134,13 @@ elseif(APPLE)
set(RESOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/misc/ogrelogo.png")
source_group(Resources FILES ${RESOURCE_FILES})
set(DEPENDENCIES ${DEPENDENCIES} "-framework Cocoa")
elseif(UNIX AND XAW_LIBRARY AND NOT OGRE_GLSUPPORT_USE_WAYLAND)
elseif(UNIX AND XAW_LIBRARY AND NOT OGRE_USE_WAYLAND)
list(APPEND SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/src/OgreGLXConfigDialog.cpp")
list(APPEND DEPENDENCIES ${X11_Xt_LIB} ${XAW_LIBRARY})
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/misc/GLX_backdrop.png" DESTINATION "${OGRE_MEDIA_PATH}/../")
endif()

if(UNIX AND NOT APPLE AND NOT OGRE_GLSUPPORT_USE_WAYLAND)
if(UNIX AND NOT APPLE AND NOT OGRE_USE_WAYLAND)
list(APPEND DEPENDENCIES ${X11_X11_LIB})
set(NATIVE_INCLUDES ${X11_Xlib_INCLUDE_PATH})
endif()
Expand Down Expand Up @@ -175,7 +175,7 @@ if(OGRE_STATIC AND APPLE AND OGRE_BUILD_PLUGIN_CG)
target_include_directories(OgreBites PUBLIC ${Cg_INCLUDE_DIRS})
endif()

if(OGRE_GLSUPPORT_USE_WAYLAND)
if(OGRE_USE_WAYLAND)
target_compile_definitions(OgreBites PRIVATE OGRE_WAYLAND)
endif()

Expand All @@ -195,7 +195,7 @@ else()
set(_OgreBitesQt OFF)
endif()

if(OGRE_GLSUPPORT_USE_WAYLAND)
if(OGRE_USE_WAYLAND)
if(NOT TARGET Qt${QT_VERSION_MAJOR}::GuiPrivate)
set(_OgreBitesQt OFF)
else()
Expand All @@ -214,7 +214,7 @@ if(_OgreBitesQt)
add_library(OgreBitesQt ${OGRE_COMP_LIB_TYPE} ${MOC_SRC} "${CMAKE_CURRENT_SOURCE_DIR}/src/OgreApplicationContextQt.cpp")
set_target_properties(OgreBitesQt PROPERTIES VERSION ${OGRE_SOVERSION} SOVERSION ${OGRE_SOVERSION})
target_link_libraries(OgreBitesQt PUBLIC Qt${QT_VERSION_MAJOR}::Gui OgreBites)
if(OGRE_GLSUPPORT_USE_WAYLAND)
if(OGRE_USE_WAYLAND)
target_compile_definitions(OgreBitesQt PRIVATE OGRE_WAYLAND)
target_link_libraries(OgreBitesQt PRIVATE Qt${QT_VERSION_MAJOR}::GuiPrivate)
target_include_directories(OgreBitesQt PRIVATE
Expand Down
8 changes: 4 additions & 4 deletions RenderSystems/GLSupport/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

if(EGL_FOUND)
cmake_dependent_option(OGRE_GLSUPPORT_USE_EGL "use EGL for GL Context Creation instead of GLX/ WGL" TRUE "NOT WIN32" FALSE)
cmake_dependent_option(OGRE_GLSUPPORT_USE_WAYLAND "use Wayland window manager" FALSE "UNIX;NOT APPLE;NOT EMSCRIPTEN;NOT ANDROID" FALSE)
cmake_dependent_option(OGRE_USE_WAYLAND "use Wayland window manager" FALSE "UNIX;NOT APPLE;NOT EMSCRIPTEN;NOT ANDROID" FALSE)
endif()

if(ANDROID)
Expand Down Expand Up @@ -68,7 +68,7 @@ elseif (UNIX)
list(APPEND _EGL_HEADERS "include/EGL/*.h")
list(APPEND _EGL_SOURCES "src/EGL/*.cpp")
list(APPEND NATIVE_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/include/EGL)
if(OGRE_GLSUPPORT_USE_WAYLAND)
if(OGRE_USE_WAYLAND)
list(APPEND _EGL_HEADERS "include/EGL/Wayland/*.h")
list(APPEND _EGL_SOURCES "src/EGL/Wayland/*.cpp")
list(APPEND NATIVE_INCLUDES
Expand Down Expand Up @@ -99,7 +99,7 @@ elseif (UNIX)

set(PLATFORM_LIBS ${X11_LIBRARIES} ${X11_Xrandr_LIB} ${OPENGL_glx_LIBRARY})
endif()
if(NOT OGRE_GLSUPPORT_USE_WAYLAND)
if(NOT OGRE_USE_WAYLAND)
list(APPEND NATIVE_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}/src/X11/")
endif()
endif ()
Expand Down Expand Up @@ -132,7 +132,7 @@ target_include_directories(OgreGLSupport PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/GLSL>"
PRIVATE "$<BUILD_INTERFACE:${NATIVE_INCLUDES}>")

if(OGRE_GLSUPPORT_USE_WAYLAND)
if(OGRE_USE_WAYLAND)
target_compile_definitions(OgreGLSupport PRIVATE OGRE_WAYLAND)
endif()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void WaylandEGLWindow::create(const String& name, uint width, uint height, bool
}

OgreAssert(miscParams->find("parentWindowHandle") == end && miscParams->find("externalWindowHandle") == end,
"Recompile with OGRE_GLSUPPORT_USE_WAYLAND=OFF");
"Recompile with OGRE_USE_WAYLAND=OFF");
}

initNativeCreatedWindow(miscParams);
Expand Down
2 changes: 1 addition & 1 deletion RenderSystems/GLSupport/src/EGL/X11/OgreX11EGLWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ namespace Ogre {
NameValuePairList::const_iterator opt;
NameValuePairList::const_iterator end = miscParams->end();

OgreAssert(miscParams->find("externalWlDisplay") == end, "Recompile with OGRE_GLSUPPORT_USE_WAYLAND=ON");
OgreAssert(miscParams->find("externalWlDisplay") == end, "Recompile with OGRE_USE_WAYLAND=ON");

if ((opt = miscParams->find("parentWindowHandle")) != end ||
(opt = miscParams->find("externalWindowHandle")) != end)
Expand Down
11 changes: 5 additions & 6 deletions RenderSystems/Vulkan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,13 @@ if(DEFINED ENV{VULKAN_SDK})
endif()

if(WIN32)
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/src/volk.c"
PROPERTIES COMPILE_DEFINITIONS VK_USE_PLATFORM_WIN32_KHR)
target_compile_definitions(RenderSystem_Vulkan PRIVATE VK_USE_PLATFORM_WIN32_KHR)
elseif(ANDROID)
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/src/volk.c"
PROPERTIES COMPILE_DEFINITIONS VK_USE_PLATFORM_ANDROID_KHR)
target_compile_definitions(RenderSystem_Vulkan PRIVATE VK_USE_PLATFORM_ANDROID_KHR)
elseif(OGRE_USE_WAYLAND)
target_compile_definitions(RenderSystem_Vulkan PRIVATE VK_USE_PLATFORM_WAYLAND_KHR)
else()
set_source_files_properties("${CMAKE_CURRENT_SOURCE_DIR}/src/volk.c"
PROPERTIES COMPILE_DEFINITIONS VK_USE_PLATFORM_XLIB_KHR)
target_compile_definitions(RenderSystem_Vulkan PRIVATE VK_USE_PLATFORM_XLIB_KHR)
target_link_libraries(RenderSystem_Vulkan PRIVATE ${X11_LIBRARIES})
endif()

Expand Down
8 changes: 0 additions & 8 deletions RenderSystems/Vulkan/include/OgreVulkanPrerequisites.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ THE SOFTWARE.
#include "OgrePixelFormat.h"

#include "OgreVulkanExports.h"
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#define VK_USE_PLATFORM_XLIB_KHR
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define VK_USE_PLATFORM_WIN32_KHR
#elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
#define VK_USE_PLATFORM_ANDROID_KHR
#endif

#include <volk.h>

#define VMA_NULLABLE
Expand Down
2 changes: 2 additions & 0 deletions RenderSystems/Vulkan/include/OgreVulkanWindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ namespace Ogre

void createSurface(size_t windowHandle);

void createSurface(size_t wlSurface, size_t wlDisplay);

std::unique_ptr<VulkanRenderPassDescriptor> mRenderPassDescriptor;

public:
Expand Down
50 changes: 42 additions & 8 deletions RenderSystems/Vulkan/src/OgreVulkanWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ namespace Ogre
//-------------------------------------------------------------------------
void VulkanWindow::createSurface(size_t windowHandle)
{
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#if defined(VK_USE_PLATFORM_XLIB_KHR)
Display *dpy = XOpenDisplay(NULL);

VkXlibSurfaceCreateInfoKHR surfCreateInfo = {VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR};
Expand All @@ -379,7 +379,7 @@ namespace Ogre
}

OGRE_VK_CHECK(vkCreateXlibSurfaceKHR(mDevice->mInstance, &surfCreateInfo, 0, &mSurfaceKHR));
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
HINSTANCE hInst = NULL;
static TCHAR staticVar;
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, &staticVar, &hInst);
Expand All @@ -389,23 +389,41 @@ namespace Ogre
surfCreateInfo.hwnd = (HWND)windowHandle;

OGRE_VK_CHECK(vkCreateWin32SurfaceKHR(mDevice->mInstance, &surfCreateInfo, 0, &mSurfaceKHR));
#elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
VkAndroidSurfaceCreateInfoKHR surfCreateInfo = {VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR};
surfCreateInfo.window = (ANativeWindow*)windowHandle;

OGRE_VK_CHECK(vkCreateAndroidSurfaceKHR(mDevice->mInstance, &surfCreateInfo, 0, &mSurfaceKHR));
#else
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unsupported Vulkan platform");
#endif
}

void VulkanWindow::createSurface(size_t wlSurface, size_t wlDisplay)
{
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
VkWaylandSurfaceCreateInfoKHR surfCreateInfo = {VK_STRUCTURE_TYPE_WAYLAND_SURFACE_CREATE_INFO_KHR};
surfCreateInfo.display = (struct wl_display*)wlDisplay;
surfCreateInfo.surface = (struct wl_surface*)wlSurface;

OGRE_VK_CHECK(vkCreateWaylandSurfaceKHR(mDevice->mInstance, &surfCreateInfo, 0, &mSurfaceKHR));
#else
OGRE_EXCEPT(Exception::ERR_RENDERINGAPI_ERROR, "Unsupported Vulkan platform");
#endif
}

const char *VulkanWindow::getRequiredExtensionName()
{
#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
#if defined(VK_USE_PLATFORM_XLIB_KHR)
return VK_KHR_XLIB_SURFACE_EXTENSION_NAME;
#elif OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#elif defined(VK_USE_PLATFORM_WAYLAND_KHR)
return VK_KHR_WAYLAND_SURFACE_EXTENSION_NAME;
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
return VK_KHR_WIN32_SURFACE_EXTENSION_NAME;
#elif OGRE_PLATFORM == OGRE_PLATFORM_ANDROID
#elif defined(VK_USE_PLATFORM_ANDROID_KHR)
return VK_KHR_ANDROID_SURFACE_EXTENSION_NAME;
#endif
return "";
}

void VulkanWindow::create(const String& name, unsigned int width, unsigned int height, bool fullScreen,
Expand All @@ -419,6 +437,8 @@ namespace Ogre
mHeight = height;
mFSAA = 1;

size_t wlDisplay = 0;

if( miscParams )
{
NameValuePairList::const_iterator end = miscParams->end();
Expand All @@ -427,6 +447,15 @@ namespace Ogre
if( opt != end )
mWindowHandle = StringConverter::parseSizeT( opt->second );

opt = miscParams->find( "externalWlSurface" );
if( opt != end )
mWindowHandle = StringConverter::parseSizeT( opt->second );


opt = miscParams->find( "externalWlDisplay" );
if( opt != end )
wlDisplay = StringConverter::parseSizeT( opt->second );

opt = miscParams->find( "vsync" );
if( opt != end )
mVSync = StringConverter::parseBool( opt->second );
Expand All @@ -441,8 +470,13 @@ namespace Ogre
mHwGamma = StringConverter::parseBool( opt->second );
}

OgreAssert( mWindowHandle, "externalWindowHandle required" );
createSurface(mWindowHandle);
#ifdef VK_USE_PLATFORM_WAYLAND_KHR
OgreAssert( mWindowHandle && wlDisplay, "externalWlSurface and externalWlDisplay required");
createSurface(mWindowHandle, wlDisplay);
#else
OgreAssert( mWindowHandle, "externalWindowHandle required");
createSurface(mWindowHandle, wlDisplay);
#endif

auto texMgr = TextureManager::getSingletonPtr();
mTexture = new VulkanTextureGpuWindow("RenderWindow", TEX_TYPE_2D, texMgr, this);;
Expand Down

0 comments on commit aab0c6a

Please sign in to comment.