Skip to content

Commit b64c441

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. This includes enabling VK_KHR_display where applicable, which is supported on linux and windows at the current time.
1 parent 4c63e84 commit b64c441

File tree

10 files changed

+2129
-883
lines changed

10 files changed

+2129
-883
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

+117-94
Original file line numberDiff line numberDiff line change
@@ -61,32 +61,58 @@ if(APPLE)
6161
endif()
6262
endif()
6363

64+
if(ANDROID)
65+
set(WSI_DISPLAY_DEFAULT_SETTING "OFF")
66+
else()
67+
set(WSI_DISPLAY_DEFAULT_SETTING "ON")
68+
endif()
69+
70+
option(BUILD_WSI_DISPLAY_SUPPORT "Build DISPLAY WSI support" ${WSI_DISPLAY_DEFAULT_SETTING})
71+
6472
if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
6573
option(BUILD_WSI_XCB_SUPPORT "Build XCB WSI support" ON)
6674
option(BUILD_WSI_XLIB_SUPPORT "Build Xlib WSI support" ON)
6775
option(BUILD_WSI_WAYLAND_SUPPORT "Build Wayland WSI support" ON)
6876
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)")
7077

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

7380
if(BUILD_WSI_XCB_SUPPORT)
7481
pkg_check_modules(XCB REQUIRED QUIET IMPORTED_TARGET xcb)
82+
pkg_get_variable(XCB_INCLUDE_DIRS xcb includedir)
83+
message(DEBUG "XCB_INCLUDE_DIRS = ${XCB_INCLUDE_DIRS}")
7584
endif()
7685

7786
if(BUILD_WSI_XLIB_SUPPORT)
7887
pkg_check_modules(X11 REQUIRED QUIET IMPORTED_TARGET x11)
88+
pkg_get_variable(XLIB_INCLUDE_DIRS x11 includedir)
89+
message(DEBUG "XLIB_INCLUDE_DIRS = ${XLIB_INCLUDE_DIRS}")
7990
endif()
8091

8192
if(BUILD_WSI_WAYLAND_SUPPORT)
8293
pkg_check_modules(WAYLAND_CLIENT REQUIRED IMPORTED_TARGET wayland-client)
94+
pkg_get_variable(WAYLAND_INCLUDE_DIRS wayland-client includedir)
8395

8496
pkg_get_variable(WAYLAND_SCANNER_EXECUTABLE wayland-scanner wayland_scanner)
85-
message(STATUS "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
97+
message(DEBUG "WAYLAND_SCANNER_EXECUTABLE = ${WAYLAND_SCANNER_EXECUTABLE}")
98+
99+
pkg_get_variable(WAYLAND_CLIENT_PATH wayland-client pkgdatadir)
100+
message(DEBUG "WAYLAND_CLIENT_PATH = ${WAYLAND_CLIENT_PATH}")
101+
set(WAYLAND_CODE_PROTOCOL ${WAYLAND_CLIENT_PATH}/wayland.xml)
86102

87103
pkg_get_variable(WAYLAND_PROTOCOLS_PATH wayland-protocols pkgdatadir)
88-
message(STATUS "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
104+
message(DEBUG "WAYLAND_PROTOCOLS_PATH = ${WAYLAND_PROTOCOLS_PATH}")
89105
set(XDG_SHELL_PROTOCOL ${WAYLAND_PROTOCOLS_PATH}/stable/xdg-shell/xdg-shell.xml)
106+
107+
add_custom_command(COMMENT "Generating wayland client protocol dispatch data"
108+
OUTPUT wayland-client.c
109+
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
110+
private-code
111+
${WAYLAND_CODE_PROTOCOL}
112+
${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
113+
MAIN_DEPENDENCY ${WAYLAND_CODE_PROTOCOL}
114+
DEPENDS ${WAYLAND_CODE_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
115+
90116
add_custom_command(COMMENT "Generating xdg-shell protocol dispatch data"
91117
OUTPUT xdg-shell-code.c
92118
COMMAND ${WAYLAND_SCANNER_EXECUTABLE}
@@ -121,66 +147,52 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
121147
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h
122148
MAIN_DEPENDENCY ${XDG_DECORATION_PROTOCOL}
123149
DEPENDS ${XDG_DECORATION_PROTOCOL} ${WAYLAND_SCANNER_EXECUTABLE})
150+
151+
set(WAYLAND_ADDITIONAL_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/wayland-client.c
152+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-code.c
153+
${CMAKE_CURRENT_BINARY_DIR}/xdg-shell-client-header.h
154+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-code.c
155+
${CMAKE_CURRENT_BINARY_DIR}/xdg-decoration-client-header.h)
124156
endif()
125157

126158
if(BUILD_WSI_DIRECTFB_SUPPORT)
127159
pkg_check_modules(DirectFB REQUIRED QUIET IMPORTED_TARGET directfb)
128160
endif()
129161
endif()
130162

163+
if(BUILD_WSI_DISPLAY_SUPPORT)
164+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DISPLAY_KHR)
165+
endif()
166+
131167
if(WIN32)
132-
add_definitions(-DVK_USE_PLATFORM_WIN32_KHR -DWIN32_LEAN_AND_MEAN -DNOMINMAX)
168+
add_definitions(-DWIN32_LEAN_AND_MEAN -DNOMINMAX)
169+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WIN32_KHR)
133170
elseif(ANDROID)
134-
add_definitions(-DVK_USE_PLATFORM_ANDROID_KHR)
171+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_ANDROID_KHR)
135172
elseif(APPLE)
136-
add_definitions(-DVK_USE_PLATFORM_METAL_EXT)
173+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_METAL_EXT)
137174
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
138-
if(NOT CUBE_WSI_SELECTION)
139-
set(CUBE_WSI_SELECTION "XCB")
175+
if(BUILD_WSI_XCB_SUPPORT)
176+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XCB_KHR)
140177
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}")
178+
if(BUILD_WSI_XLIB_SUPPORT)
179+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_XLIB_KHR)
180+
endif()
181+
if(BUILD_WSI_WAYLAND_SUPPORT)
182+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_WAYLAND_KHR)
183+
endif()
184+
if(BUILD_WSI_DIRECTFB_SUPPORT)
185+
list(APPEND ENABLED_CUBE_PLATFORMS VK_USE_PLATFORM_DIRECTFB_EXT)
177186
endif()
178-
179187
link_libraries(${API_LOWERCASE} m)
180188
else()
181189
message(FATAL_ERROR "Unsupported Platform!")
182190
endif()
183191

192+
if(NOT DEFINED ENABLED_CUBE_PLATFORMS)
193+
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")
194+
endif()
195+
184196
if (COMPILE_CUBE_SHADERS)
185197
# Try to find glslang in system paths or in an SDK if the VULKAN_SDK env-var is set
186198
find_program(GLSLANG_VALIDATOR names glslang glslangValidator HINTS $ENV{GLSLANG_INSTALL_DIR} $ENV{VULKAN_SDK}/bin $ENV{VULKAN_SDK}/Bin)
@@ -226,7 +238,6 @@ elseif (ANDROID)
226238

227239
add_subdirectory(android)
228240

229-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
230241
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
231242
add_executable(vkcube)
232243
target_sources(vkcube PRIVATE
@@ -235,15 +246,28 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
235246
${PROJECT_SOURCE_DIR}/cube/cube.frag
236247
cube.vert.inc
237248
cube.frag.inc
238-
${OPTIONAL_WAYLAND_DATA_FILES}
239249
)
240-
target_compile_definitions(vkcube PUBLIC ${CUBE_PLATFORM})
250+
target_link_libraries(vkcube Threads::Threads)
251+
if(BUILD_WSI_XCB_SUPPORT)
252+
target_sources(vkcube PRIVATE xcb_loader.h)
253+
target_include_directories(vkcube PRIVATE ${xcb_INCLUDE_DIRS})
254+
endif()
255+
if(BUILD_WSI_XLIB_SUPPORT)
256+
target_sources(vkcube PRIVATE xlib_loader.h)
257+
target_include_directories(vkcube PRIVATE ${XLIB_INCLUDE_DIRS})
258+
endif()
259+
if(BUILD_WSI_WAYLAND_SUPPORT)
260+
target_include_directories(vkcube PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
261+
target_sources(vkcube PRIVATE PRIVATE ${WAYLAND_ADDITIONAL_SOURCES})
262+
endif()
263+
if(BUILD_WSI_DIRECTFB_SUPPORT)
264+
target_link_libraries(vkcube PkgConfig::DirectFB)
265+
endif()
241266
include(CheckLibraryExists)
242267
CHECK_LIBRARY_EXISTS("rt" clock_gettime "" NEED_RT)
243268
if (NEED_RT)
244-
target_link_libraries(vkcube PRIVATE rt)
269+
target_link_libraries(vkcube rt)
245270
endif()
246-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers Threads::Threads)
247271
elseif(WIN32)
248272
add_executable(vkcube WIN32)
249273
target_sources(vkcube PRIVATE
@@ -253,12 +277,13 @@ elseif(WIN32)
253277
cube.vert.inc
254278
cube.frag.inc
255279
)
256-
target_link_libraries(vkcube PRIVATE Vulkan::Headers volk::volk_headers)
257280
else()
258281
message(FATAL_ERROR "Unsupported Platform!")
259282
endif()
260283

284+
target_compile_definitions(vkcube PRIVATE ${ENABLED_CUBE_PLATFORMS})
261285
target_include_directories(vkcube PRIVATE .)
286+
target_link_libraries(vkcube Vulkan::Headers volk::volk_headers)
262287

263288
if (ANDROID)
264289
install(TARGETS vkcube DESTINATION ${CMAKE_INSTALL_LIBDIR})
@@ -280,6 +305,16 @@ if (ANDROID)
280305
return()
281306
endif()
282307

308+
if (XCB_LINK_LIBRARIES)
309+
target_compile_definitions(vkcube PRIVATE "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
310+
endif()
311+
if (X11_LINK_LIBRARIES)
312+
target_compile_definitions(vkcube PRIVATE "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
313+
endif()
314+
if (WAYLAND_CLIENT_LINK_LIBRARIES)
315+
target_compile_definitions(vkcube PRIVATE "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
316+
endif()
317+
283318
# ----------------------------------------------------------------------------
284319
# vkcubepp
285320

@@ -291,10 +326,24 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|BSD|GNU")
291326
${PROJECT_SOURCE_DIR}/cube/cube.vert
292327
${PROJECT_SOURCE_DIR}/cube/cube.frag
293328
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})
329+
cube.frag.inc)
330+
target_link_libraries(vkcubepp Threads::Threads)
331+
332+
if(BUILD_WSI_XCB_SUPPORT)
333+
target_sources(vkcubepp PRIVATE xcb_loader.h)
334+
target_include_directories(vkcubepp PRIVATE ${xcb_INCLUDE_DIRS})
335+
endif()
336+
if(BUILD_WSI_XLIB_SUPPORT)
337+
target_sources(vkcubepp PRIVATE xlib_loader.h)
338+
target_include_directories(vkcubepp PRIVATE ${XLIB_INCLUDE_DIRS})
339+
endif()
340+
if(BUILD_WSI_WAYLAND_SUPPORT)
341+
target_include_directories(vkcubepp PRIVATE ${WAYLAND_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR})
342+
target_sources(vkcubepp PRIVATE ${WAYLAND_ADDITIONAL_SOURCES})
343+
endif()
344+
if(BUILD_WSI_DIRECTFB_SUPPORT)
345+
target_link_libraries(vkcubepp PkgConfig::DirectFB)
346+
endif()
298347
else()
299348
add_executable(vkcubepp
300349
WIN32
@@ -303,9 +352,21 @@ else()
303352
${PROJECT_SOURCE_DIR}/cube/cube.frag
304353
cube.vert.inc
305354
cube.frag.inc)
306-
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers)
307355
endif()
356+
308357
target_include_directories(vkcubepp PRIVATE .)
358+
target_compile_definitions(vkcubepp PRIVATE ${ENABLED_CUBE_PLATFORMS})
359+
target_link_libraries(vkcubepp Vulkan::Headers volk::volk_headers)
360+
361+
if (XCB_LINK_LIBRARIES )
362+
target_compile_definitions(vkcubepp PUBLIC "XCB_LIBRARY=\"${XCB_LINK_LIBRARIES}\"")
363+
endif()
364+
if (X11_LINK_LIBRARIES)
365+
target_compile_definitions(vkcubepp PUBLIC "XLIB_LIBRARY=\"${X11_LINK_LIBRARIES}\"")
366+
endif()
367+
if (WAYLAND_CLIENT_LINK_LIBRARIES)
368+
target_compile_definitions(vkcubepp PUBLIC "WAYLAND_LIBRARY=\"${WAYLAND_CLIENT_LINK_LIBRARIES}\"")
369+
endif()
309370

310371
if(APPLE)
311372
install(
@@ -320,41 +381,3 @@ if(APPLE)
320381
else()
321382
install(TARGETS vkcubepp)
322383
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()

cube/android/CMakeLists.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ target_sources(android_glue PRIVATE
4343

4444
set_target_properties(vkcube PROPERTIES OUTPUT_NAME "VkCube")
4545

46-
target_link_libraries(vkcube PRIVATE
46+
target_link_libraries(vkcube
4747
android_glue
4848
log
4949
android

0 commit comments

Comments
 (0)