Skip to content

Commit 615c292

Browse files
cube: Support runtime selection of WSI platform
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.
1 parent 4c63e84 commit 615c292

File tree

9 files changed

+2118
-876
lines changed

9 files changed

+2118
-876
lines changed

.github/workflows/tools.yml

+5-15
Original file line numberDiff line numberDiff line change
@@ -38,26 +38,17 @@ jobs:
3838
cxx: [ g++ ]
3939
config: [ Debug, Release ]
4040
os: [ ubuntu-20.04, ubuntu-22.04 ]
41-
cube_wsi: [ XCB ]
4241
include:
43-
# Test WAYLAND
44-
- cc: gcc
45-
cxx: g++
46-
config: Release
47-
os: ubuntu-22.04
48-
cube_wsi: WAYLAND
49-
# Test clang on ubuntu 20 with XLIB
42+
# Test clang on ubuntu 20
5043
- cc: clang
5144
cxx: clang++
5245
config: Debug
5346
os: ubuntu-20.04
54-
cube_wsi: XLIB
55-
# Test clang on ubuntu 22 with the DISPLAY option
47+
# Test clang on ubuntu 22
5648
- cc: clang
5749
cxx: clang++
5850
config: Release
5951
os: ubuntu-22.04
60-
cube_wsi: DISPLAY
6152

6253

6354
steps:
@@ -67,19 +58,18 @@ jobs:
6758
python-version: '3.7'
6859
- run: |
6960
sudo apt-get -qq update
70-
sudo apt install libwayland-dev xorg-dev wayland-protocols
61+
sudo apt install --yes libwayland-dev xorg-dev wayland-protocols
7162
- uses: lukka/get-cmake@latest
7263
with:
7364
cmakeVersion: 3.17.2
7465
- name: Setup ccache
7566
uses: hendrikmuhs/ccache-action@v1.2
7667
with:
77-
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.cc }}-${{matrix.cube_wsi}}
68+
key: ${{ runner.os }}-${{ matrix.config }}-${{ matrix.cc }}
7869
- name: Configure
7970
run: |
8071
cmake -S. -B build -G "Ninja" \
8172
-D CMAKE_BUILD_TYPE=${{matrix.config}} \
82-
-D CUBE_WSI_SELECTION=${{matrix.cube_wsi}} \
8373
-D UPDATE_DEPS=ON \
8474
-D BUILD_WERROR=ON \
8575
-D INSTALL_ICD=ON \
@@ -231,7 +221,7 @@ jobs:
231221
- uses: actions/setup-python@v5
232222
with:
233223
python-version: '3.10'
234-
- run: sudo apt-get -qq update && sudo apt install libwayland-dev xorg-dev wayland-protocols
224+
- run: sudo apt-get -qq update && sudo apt install --yes libwayland-dev xorg-dev wayland-protocols
235225
- run: cmake -S . -B build/ -D UPDATE_DEPS=ON -D UPDATE_DEPS_DIR=external -D TOOLS_CODEGEN=ON
236226
- run: cmake --build build --target tools_codegen
237227
- run: git diff --exit-code

cube/CMakeLists.txt

+127-93
Original file line numberDiff line numberDiff line change
@@ -61,32 +61,61 @@ if(APPLE)
6161
endif()
6262
endif()
6363

64+
option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ON)
65+
6466
if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
6567
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
6668
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
6769
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
6870
option(BUILD_WSI_DIRECTFB_SUPPORT "Build DirectFB WSI support" OFF)
69-
set(CUBE_WSI_SELECTION "XCB" CACHE STRING "Select WSI target for vkcube (XCB, XLIB, WAYLAND, DIRECTFB, DISPLAY)")
7071

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

7374
if(BUILD_WSI_XCB_SUPPORT)
7475
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
76+
pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir)
77+
message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}")
7578
endif()
7679

7780
if(BUILD_WSI_XLIB_SUPPORT)
7881
pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
82+
pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
83+
message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}")
7984
endif()
8085

8186
if(BUILD_WSI_WAYLAND_SUPPORT)
8287
pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client)
88+
pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir)
8389

8490
pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner)
85-
message(STATUS "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
91+
message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
92+
93+
pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir)
94+
message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}")
95+
set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml)
8696

8797
pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir)
88-
message(STATUS "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
98+
message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
8999
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)
100+
101+
add_custom_command(COMMENT "Generating wayland client protocol dispatch data"
102+
OUTPUT wayland-client.c
103+
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
104+
private-code
105+
${WAYLAND_CODE_PROTOCOL}
106+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
107+
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
108+
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
109+
110+
add_custom_command(COMMENT "Generating wayland client protocol header"
111+
OUTPUT wayland-client-header.h
112+
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
113+
client-header
114+
${WAYLAND_CODE_PROTOCOL}
115+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
116+
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
117+
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
118+
90119
add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data"
91120
OUTPUT xdg-shell-code.c
92121
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
@@ -128,59 +157,39 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
128157
endif()
129158
endif()
130159

160+
if(BUILD_WSI_DISPLAY_SUPPORT)
161+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR)
162+
endif()
163+
131164
if(WIN32)
132-
add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN -DNOMINMAX)
165+
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX)
166+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR)
133167
elseif(ANDROID)
134-
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
168+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR)
135169
elseif(APPLE)
136-
add_definitions(-DVK_USE_PLATFORM_METAL_EXT)
170+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT)
137171
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
138-
if(NOT CUBE_WSI_SELECTION)
139-
set(CUBE_WSI_SELECTION "XCB")
172+
if(BUILD_WSI_XCB_SUPPORT)
173+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR)
140174
endif()
141-
142-
if(CUBE_WSI_SELECTION STREQUAL "XCB")
143-
if(NOT BUILD_WSI_XCB_SUPPORT)
144-
message(FATAL_ERROR "Selected XCB for vkcube build but not building Xcb support")
145-
endif()
146-
link_libraries(PkgConfig::XCB)
147-
set(CUBE_PLATFORM VK_USE_PLATFORM_XCB_KHR)
148-
elseif(CUBE_WSI_SELECTION STREQUAL "XLIB")
149-
if(NOT BUILD_WSI_XLIB_SUPPORT)
150-
message(FATAL_ERROR "Selected XLIB for vkcube build but not building Xlib support")
151-
endif()
152-
link_libraries(PkgConfig::X11)
153-
set(CUBE_PLATFORM VK_USE_PLATFORM_XLIB_KHR)
154-
elseif(CUBE_WSI_SELECTION STREQUAL "WAYLAND")
155-
if(NOT BUILD_WSI_WAYLAND_SUPPORT)
156-
message(FATAL_ERROR "Selected Wayland for vkcube build but not building Wayland support")
157-
endif()
158-
link_libraries(PkgConfig::WAYLAND_CLIENT)
159-
set(CUBE_PLATFORM VK_USE_PLATFORM_WAYLAND_KHR)
160-
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)
161-
set(OPTIONAL_WAYLAND_DATA_FILES
162-
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
163-
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
164-
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
165-
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h)
166-
include_directories(${CMAKE_CURRENT_BINARY_DIR})
167-
elseif(CUBE_WSI_SELECTION STREQUAL "DIRECTFB")
168-
if(NOT BUILD_WSI_DIRECTFB_SUPPORT)
169-
message(FATAL_ERROR "Selected DIRECTFB for vkcube build but not building DirectFB support")
170-
endif()
171-
link_libraries(PkgConfig::DirectFB)
172-
set(CUBE_PLATFORM VK_USE_PLATFORM_DIRECTFB_EXT)
173-
elseif(CUBE_WSI_SELECTION STREQUAL "DISPLAY")
174-
set(CUBE_PLATFORM VK_USE_PLATFORM_DISPLAY_KHR)
175-
else()
176-
message(FATAL_ERROR "Unrecognized value for CUBE_WSI_SELECTION: ${CUBE_WSI_SELECTION}")
175+
if(BUILD_WSI_XLIB_SUPPORT)
176+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR)
177+
endif()
178+
if(BUILD_WSI_WAYLAND_SUPPORT)
179+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR)
180+
endif()
181+
if(BUILD_WSI_DIRECTFB_SUPPORT)
182+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT)
177183
endif()
178-
179184
link_libraries(${API_LOWERCASE} m)
180185
else()
181186
message(FATAL_ERROR "Unsupported Platform!")
182187
endif()
183188

189+
if(NOT DEFINED ENABLED_CUBE_PLATFORMS)
190+
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")
191+
endif()
192+
184193
if (COMPILE_CUBE_SHADERS)
185194
# Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set
186195
find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin)
@@ -226,7 +235,6 @@ elseif (ANDROID)
226235

227236
add_subdirectory(android)
228237

229-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
230238
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
231239
add_executable(vkcube)
232240
target_sources(vkcube PRIVATE
@@ -235,15 +243,35 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
235243
${PROJECT_SOURCE_DIR}/cube/cube.frag
236244
cube.vert.inc
237245
cube.frag.inc
238-
${OPTIONAL_WAYLAND_DATA_FILES}
239246
)
240-
target_compile_definitions(vkcube PUBLIC ${CUBE_PLATFORM})
247+
target_link_libraries(vkcube PRIVATE Threads::Threads)
248+
if(BUILD_WSI_XCB_SUPPORT)
249+
target_sources(vkcube PRIVATE xcb_loader.h)
250+
target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS})
251+
endif()
252+
if(BUILD_WSI_XLIB_SUPPORT)
253+
target_sources(vkcube PRIVATE xlib_loader.h)
254+
target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS})
255+
endif()
256+
if(BUILD_WSI_WAYLAND_SUPPORT)
257+
target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
258+
target_sources(vkcube PRIVATE
259+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
260+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
261+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
262+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
263+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
264+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
265+
)
266+
endif()
267+
if(BUILD_WSI_DIRECTFB_SUPPORT)
268+
target_link_libraries(vkcube PRIVATE PkgConfig::DirectFB)
269+
endif()
241270
include(CheckLibraryExists)
242271
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
243272
if (NEED_RT)
244273
target_link_libraries(vkcube PRIVATE rt)
245274
endif()
246-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers Threads::Threads)
247275
elseif(WIN32)
248276
add_executable(vkcube WIN32)
249277
target_sources(vkcube PRIVATE
@@ -253,12 +281,13 @@ elseif(WIN32)
253281
cube.vert.inc
254282
cube.frag.inc
255283
)
256-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
257284
else()
258285
message(FATAL_ERROR "Unsupported Platform!")
259286
endif()
260287

288+
target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS})
261289
target_include_directories(vkcube PRIVATE .)
290+
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
262291

263292
if (ANDROID)
264293
install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR})
@@ -280,6 +309,16 @@ if (ANDROID)
280309
return()
281310
endif()
282311

312+
if (XCB_LINK_LIBRARIES)
313+
target_compile_definitions(vkcube PRIVATE "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
314+
endif()
315+
if (X11_LINK_LIBRARIES)
316+
target_compile_definitions(vkcube PRIVATE "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
317+
endif()
318+
if (WAYLAND_CLIENT_LINK_LIBRARIES)
319+
target_compile_definitions(vkcube PRIVATE "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
320+
endif()
321+
283322
# ----------------------------------------------------------------------------
284323
# vkcubepp
285324

@@ -291,10 +330,31 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
291330
${PROJECT_SOURCE_DIR}/cube/cube.vert
292331
${PROJECT_SOURCE_DIR}/cube/cube.frag
293332
cube.vert.inc
294-
cube.frag.inc
295-
${OPTIONAL_WAYLAND_DATA_FILES})
296-
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers Threads::Threads)
297-
target_compile_definitions(vkcubepp PUBLIC ${CUBE_PLATFORM})
333+
cube.frag.inc)
334+
target_link_libraries(vkcubepp PRIVATE Threads::Threads)
335+
336+
if(BUILD_WSI_XCB_SUPPORT)
337+
target_sources(vkcubepp PRIVATE xcb_loader.h)
338+
target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS})
339+
endif()
340+
if(BUILD_WSI_XLIB_SUPPORT)
341+
target_sources(vkcubepp PRIVATE xlib_loader.h)
342+
target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS})
343+
endif()
344+
if(BUILD_WSI_WAYLAND_SUPPORT)
345+
target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
346+
target_sources(vkcubepp PRIVATE
347+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client-header.h
348+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
349+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
350+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
351+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
352+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
353+
)
354+
endif()
355+
if(BUILD_WSI_DIRECTFB_SUPPORT)
356+
target_link_libraries(vkcubepp PRIVATE PkgConfig::DirectFB)
357+
endif()
298358
else()
299359
add_executable(vkcubepp
300360
WIN32
@@ -303,9 +363,21 @@ else()
303363
${PROJECT_SOURCE_DIR}/cube/cube.frag
304364
cube.vert.inc
305365
cube.frag.inc)
306-
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers)
307366
endif()
367+
308368
target_include_directories(vkcubepp PRIVATE .)
369+
target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS})
370+
target_link_libraries(vkcubepp PRIVATE Vulkan::Headers volk::volk_headers)
371+
372+
if (XCB_LINK_LIBRARIES )
373+
target_compile_definitions(vkcubepp PUBLIC "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
374+
endif()
375+
if (X11_LINK_LIBRARIES)
376+
target_compile_definitions(vkcubepp PUBLIC "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
377+
endif()
378+
if (WAYLAND_CLIENT_LINK_LIBRARIES)
379+
target_compile_definitions(vkcubepp PUBLIC "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
380+
endif()
309381

310382
if(APPLE)
311383
install(
@@ -320,41 +392,3 @@ if(APPLE)
320392
else()
321393
install(TARGETS vkcubepp)
322394
endif()
323-
324-
# ----------------------------------------------------------------------------
325-
# vkcube-wayland
326-
327-
if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD")
328-
if(BUILD_WSI_WAYLAND_SUPPORT AND EXISTS ${WAYLAND_PROTOCOLS_PATH}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml)
329-
add_executable(vkcube-wayland)
330-
331-
target_sources(vkcube-wayland PRIVATE
332-
cube.c
333-
${PROJECT_SOURCE_DIR}/cube/cube.vert
334-
${PROJECT_SOURCE_DIR}/cube/cube.frag
335-
cube.vert.inc
336-
cube.frag.inc
337-
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
338-
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
339-
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
340-
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
341-
)
342-
target_include_directories(vkcube-wayland PRIVATE
343-
${CMAKE_CURRENT_BINARY_DIR}
344-
.
345-
)
346-
target_link_libraries(vkcube-wayland PRIVATE
347-
Vulkan::Headers
348-
volk::volk_headers
349-
Threads::Threads
350-
PkgConfig::WAYLAND_CLIENT
351-
)
352-
target_compile_definitions(vkcube-wayland PRIVATE VK_USE_PLATFORM_WAYLAND_KHR)
353-
include(CheckLibraryExists)
354-
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
355-
if (NEED_RT)
356-
target_link_libraries(vkcube-wayland PRIVATE rt)
357-
endif()
358-
install(TARGETS vkcube-wayland)
359-
endif()
360-
endif()

0 commit comments

Comments
 (0)