Skip to content

Commit

Permalink
cube: Support runtime selection of WSI platform
Browse files Browse the repository at this point in the history
By changing the selection of a WSI platform from a build time choice to a
runtime choice, this allows the removal of vkcube-wayland as a separate
binary.

Use `--wsi <platform>` to choose the WSI platform that vkcube will render
with. The chosen platform must be one that vkcube was compiled with
support for, so directfb will be unavailable without changing the build
parameters to enable it.

These changes have been made to both vkcube and vkcubepp.
  • Loading branch information
charles-lunarg committed Sep 5, 2024
1 parent 4c63e84 commit 615c292
Show file tree
Hide file tree
Showing 9 changed files with 2,118 additions and 876 deletions.
20 changes: 5 additions & 15 deletions .github/workflows/tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,26 +38,17 @@ jobs:
cxx: [ g++ ]
config: [ Debug, Release ]
os: [ ubuntu-20.04, ubuntu-22.04 ]
cube_wsi: [ XCB ]
include:
# Test WAYLAND
- cc: gcc
cxx: g++
config: Release
os: ubuntu-22.04
cube_wsi: WAYLAND
# Test clang on ubuntu 20 with XLIB
# Test clang on ubuntu 20
- cc: clang
cxx: clang++
config: Debug
os: ubuntu-20.04
cube_wsi: XLIB
# Test clang on ubuntu 22 with the DISPLAY option
# Test clang on ubuntu 22
- cc: clang
cxx: clang++
config: Release
os: ubuntu-22.04
cube_wsi: DISPLAY


steps:
Expand All @@ -67,19 +58,18 @@ jobs:
python-version: '3.7'
- run: |
sudo apt-get -qq update
sudo apt install libwayland-dev xorg-dev wayland-protocols
sudo apt install --yes libwayland-dev xorg-dev wayland-protocols
- uses: lukka/get-cmake@latest
with:
cmakeVersion: 3.17.2
- name: Setup ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.cc }}-${{matrix.cube_wsi}}
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.cc }}
- name: Configure
run: |
cmake -S. -B build -G "Ninja" \
-D CMAKE_BUILD_TYPE=${{matrix.config}} \
-D CUBE_WSI_SELECTION=${{matrix.cube_wsi}} \
-D UPDATE_DEPS=ON \
-D BUILD_WERROR=ON \
-D INSTALL_ICD=ON \
Expand Down Expand Up @@ -231,7 +221,7 @@ jobs:
- uses: actions/setup-python@v5
with:
python-version: '3.10'
- run: sudo apt-get -qq update && sudo apt install libwayland-dev xorg-dev wayland-protocols
- run: sudo apt-get -qq update && sudo apt install --yes libwayland-dev xorg-dev wayland-protocols
- run: cmake -S . -B build/ -D UPDATE_DEPS=ON -D UPDATE_DEPS_DIR=external -D TOOLS_CODEGEN=ON
- run: cmake --build build --target tools_codegen
- run: git diff --exit-code
Expand Down
220 changes: 127 additions & 93 deletions cube/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,32 +61,61 @@ if(APPLE)
endif()
endif()

option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ON)

if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
set(CUBE_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for vkcube (XCB, XLIB, WAYLAND, DIRECTFB, DISPLAY)")

find_package(PkgConfig REQUIRED QUIET) # Use PkgConfig to find Linux system libraries

if(BUILD_WSI_XCB_SUPPORT)
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir)
message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}")
endif()

if(BUILD_WSI_XLIB_SUPPORT)
pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}")
endif()

if(BUILD_WSI_WAYLAND_SUPPORT)
pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client)
pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir)

pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner)
message(STATUS "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")

pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir)
message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}")
set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml)

pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir)
message(STATUS "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)

add_custom_command(COMMENT "Generating wayland client protocol dispatch data"
OUTPUT wayland-client.c
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
private-code
${WAYLAND_CODE_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})

add_custom_command(COMMENT "Generating wayland client protocol header"
OUTPUT wayland-client-header.h
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
client-header
${WAYLAND_CODE_PROTOCOL}
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})

add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data"
OUTPUT xdg-shell-code.c
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
Expand Down Expand Up @@ -128,59 +157,39 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
endif()
endif()

if(BUILD_WSI_DISPLAY_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR)
endif()

if(WIN32)
add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN -DNOMINMAX)
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR)
elseif(ANDROID)
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR)
elseif(APPLE)
add_definitions(-DVK_USE_PLATFORM_METAL_EXT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
if(NOT CUBE_WSI_SELECTION)
set(CUBE_WSI_SELECTION "XCB")
if(BUILD_WSI_XCB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR)
endif()

if(CUBE_WSI_SELECTION STREQUAL "XCB")
if(NOT BUILD_WSI_XCB_SUPPORT)
message(FATAL_ERROR "Selected XCB for vkcube build but not building Xcb support")
endif()
link_libraries(PkgConfig::XCB)
set(CUBE_PLATFORM VK_USE_PLATFORM_XCB_KHR)
elseif(CUBE_WSI_SELECTION STREQUAL "XLIB")
if(NOT BUILD_WSI_XLIB_SUPPORT)
message(FATAL_ERROR "Selected XLIB for vkcube build but not building Xlib support")
endif()
link_libraries(PkgConfig::X11)
set(CUBE_PLATFORM VK_USE_PLATFORM_XLIB_KHR)
elseif(CUBE_WSI_SELECTION STREQUAL "WAYLAND")
if(NOT BUILD_WSI_WAYLAND_SUPPORT)
message(FATAL_ERROR "Selected Wayland for vkcube build but not building Wayland support")
endif()
link_libraries(PkgConfig::WAYLAND_CLIENT)
set(CUBE_PLATFORM VK_USE_PLATFORM_WAYLAND_KHR)
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)
set(OPTIONAL_WAYLAND_DATA_FILES
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
elseif(CUBE_WSI_SELECTION STREQUAL "DIRECTFB")
if(NOT BUILD_WSI_DIRECTFB_SUPPORT)
message(FATAL_ERROR "Selected DIRECTFB for vkcube build but not building DirectFB support")
endif()
link_libraries(PkgConfig::DirectFB)
set(CUBE_PLATFORM VK_USE_PLATFORM_DIRECTFB_EXT)
elseif(CUBE_WSI_SELECTION STREQUAL "DISPLAY")
set(CUBE_PLATFORM VK_USE_PLATFORM_DISPLAY_KHR)
else()
message(FATAL_ERROR "Unrecognized value for CUBE_WSI_SELECTION: ${CUBE_WSI_SELECTION}")
if(BUILD_WSI_XLIB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR)
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT)
endif()

link_libraries(${API_LOWERCASE} m)
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()

if(NOT DEFINED ENABLED_CUBE_PLATFORMS)
message(FATAL_ERROR "There are no supported WSI platforms on this system, vkcube requires a WSI platform be available to be able to render its output")
endif()

if (COMPILE_CUBE_SHADERS)
# Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set
find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin)
Expand Down Expand Up @@ -226,7 +235,6 @@ elseif (ANDROID)

add_subdirectory(android)

target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
add_executable(vkcube)
target_sources(vkcube PRIVATE
Expand All @@ -235,15 +243,35 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc
${OPTIONAL_WAYLAND_DATA_FILES}
)
target_compile_definitions(vkcube PUBLIC ${CUBE_PLATFORM})
target_link_libraries(vkcube PRIVATE Threads::Threads)
if(BUILD_WSI_XCB_SUPPORT)
target_sources(vkcube PRIVATE xcb_loader.h)
target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS})
endif()
if(BUILD_WSI_XLIB_SUPPORT)
target_sources(vkcube PRIVATE xlib_loader.h)
target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS})
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
target_sources(vkcube PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
target_link_libraries(vkcube PRIVATE PkgConfig::DirectFB)
endif()
include(CheckLibraryExists)
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
if (NEED_RT)
target_link_libraries(vkcube PRIVATE rt)
endif()
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers Threads::Threads)
elseif(WIN32)
add_executable(vkcube WIN32)
target_sources(vkcube PRIVATE
Expand All @@ -253,12 +281,13 @@ elseif(WIN32)
cube.vert.inc
cube.frag.inc
)
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
else()
message(FATAL_ERROR "Unsupported Platform!")
endif()

target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS})
target_include_directories(vkcube PRIVATE .)
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)

if (ANDROID)
install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR})
Expand All @@ -280,6 +309,16 @@ if (ANDROID)
return()
endif()

if (XCB_LINK_LIBRARIES)
target_compile_definitions(vkcube PRIVATE "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
endif()
if (X11_LINK_LIBRARIES)
target_compile_definitions(vkcube PRIVATE "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
endif()
if (WAYLAND_CLIENT_LINK_LIBRARIES)
target_compile_definitions(vkcube PRIVATE "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
endif()

# ----------------------------------------------------------------------------
# vkcubepp

Expand All @@ -291,10 +330,31 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc
${OPTIONAL_WAYLAND_DATA_FILES})
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers Threads::Threads)
target_compile_definitions(vkcubepp PUBLIC ${CUBE_PLATFORM})
cube.frag.inc)
target_link_libraries(vkcubepp PRIVATE Threads::Threads)

if(BUILD_WSI_XCB_SUPPORT)
target_sources(vkcubepp PRIVATE xcb_loader.h)
target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS})
endif()
if(BUILD_WSI_XLIB_SUPPORT)
target_sources(vkcubepp PRIVATE xlib_loader.h)
target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS})
endif()
if(BUILD_WSI_WAYLAND_SUPPORT)
target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
target_sources(vkcubepp PRIVATE
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
)
endif()
if(BUILD_WSI_DIRECTFB_SUPPORT)
target_link_libraries(vkcubepp PRIVATE PkgConfig::DirectFB)
endif()
else()
add_executable(vkcubepp
WIN32
Expand All @@ -303,9 +363,21 @@ else()
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc)
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers)
endif()

target_include_directories(vkcubepp PRIVATE .)
target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS})
target_link_libraries(vkcubepp PRIVATE Vulkan::Headers volk::volk_headers)

if (XCB_LINK_LIBRARIES )
target_compile_definitions(vkcubepp PUBLIC "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
endif()
if (X11_LINK_LIBRARIES)
target_compile_definitions(vkcubepp PUBLIC "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
endif()
if (WAYLAND_CLIENT_LINK_LIBRARIES)
target_compile_definitions(vkcubepp PUBLIC "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
endif()

if(APPLE)
install(
Expand All @@ -320,41 +392,3 @@ if(APPLE)
else()
install(TARGETS vkcubepp)
endif()

# ----------------------------------------------------------------------------
# vkcube-wayland

if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD")
if(BUILD_WSI_WAYLAND_SUPPORT AND EXISTS ${WAYLAND_PROTOCOLS_PATH}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
add_executable(vkcube-wayland)

target_sources(vkcube-wayland PRIVATE
cube.c
${PROJECT_SOURCE_DIR}/cube/cube.vert
${PROJECT_SOURCE_DIR}/cube/cube.frag
cube.vert.inc
cube.frag.inc
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
)
target_include_directories(vkcube-wayland PRIVATE
${CMAKE_CURRENT_BINARY_DIR}
.
)
target_link_libraries(vkcube-wayland PRIVATE
Vulkan::Headers
volk::volk_headers
Threads::Threads
PkgConfig::WAYLAND_CLIENT
)
target_compile_definitions(vkcube-wayland PRIVATE VK_USE_PLATFORM_WAYLAND_KHR)
include(CheckLibraryExists)
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
if (NEED_RT)
target_link_libraries(vkcube-wayland PRIVATE rt)
endif()
install(TARGETS vkcube-wayland)
endif()
endif()
Loading

0 comments on commit 615c292

Please sign in to comment.