Skip to content

Commit 98d6bdb

Browse files
committed
Daemon-vulkan infrastructure 2
1 parent 1250369 commit 98d6bdb

File tree

7 files changed

+588
-35
lines changed

7 files changed

+588
-35
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,5 +57,8 @@ external_deps/*
5757
.vs
5858
.vscode
5959

60+
#ignore python cache
61+
*.pyc
62+
6063
#ignore removed recastnavigation submodule
6164
libs/recastnavigation

CMakeLists.txt

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ endif()
641641
if (USE_VULKAN)
642642
add_definitions("-DDAEMON_RENDERER_VULKAN=1")
643643
add_definitions("-DVK_NO_PROTOTYPES=1")
644+
include(DaemonVulkan)
644645
else()
645646
add_definitions("-DDAEMON_RENDERER_OPENGL=1")
646647

@@ -1037,39 +1038,43 @@ if (BUILD_CLIENT)
10371038
Tests ${CLIENTTESTLIST}
10381039
)
10391040

1040-
# generate glsl include files
1041-
set(GLSL_SOURCE_DIR ${ENGINE_DIR}/renderer/glsl_source)
1042-
set(EMBED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed_data)
1043-
file(MAKE_DIRECTORY ${EMBED_INCLUDE_DIR})
1044-
1045-
set(SHADERS_CPP_TEXT "// This file is auto-generated by CMakeLists.txt.\n")
1046-
string(APPEND SHADERS_CPP_TEXT "#include \"common/Common.h\"\n\n")
1047-
set(SHADERMAP_TEXT "")
1048-
1049-
foreach(res ${GLSLSOURCELIST})
1050-
get_filename_component(filename_no_ext ${res} NAME_WE)
1051-
set(outpath ${EMBED_INCLUDE_DIR}/${filename_no_ext}.glsl.h)
1052-
1053-
add_custom_command(
1054-
OUTPUT ${outpath}
1055-
COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}"
1056-
"-DVARIABLE_NAME=${filename_no_ext}_glsl" -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake
1057-
MAIN_DEPENDENCY ${res}
1058-
)
1041+
if (USE_VULKAN)
1042+
GenerateVulkanShaders( client-objects )
1043+
else()
1044+
# generate glsl include files
1045+
set(GLSL_SOURCE_DIR ${ENGINE_DIR}/renderer/glsl_source)
1046+
set(EMBED_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/embed_data)
1047+
file(MAKE_DIRECTORY ${EMBED_INCLUDE_DIR})
1048+
1049+
set(SHADERS_CPP_TEXT "// This file is auto-generated by CMakeLists.txt.\n")
1050+
string(APPEND SHADERS_CPP_TEXT "#include \"common/Common.h\"\n\n")
1051+
set(SHADERMAP_TEXT "")
1052+
1053+
foreach(res ${GLSLSOURCELIST})
1054+
get_filename_component(filename_no_ext ${res} NAME_WE)
1055+
set(outpath ${EMBED_INCLUDE_DIR}/${filename_no_ext}.glsl.h)
1056+
1057+
add_custom_command(
1058+
OUTPUT ${outpath}
1059+
COMMAND ${CMAKE_COMMAND} "-DINPUT_FILE=${res}" "-DOUTPUT_FILE=${outpath}"
1060+
"-DVARIABLE_NAME=${filename_no_ext}_glsl" "-DFILE_FORMAT=TEXT" "-DEMBED_MODE=WRITE" -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake
1061+
MAIN_DEPENDENCY ${res}
1062+
)
10591063

1060-
set_property(TARGET client-objects APPEND PROPERTY SOURCES ${outpath})
1064+
set_property(TARGET client-objects APPEND PROPERTY SOURCES ${outpath})
10611065

1062-
string(APPEND SHADERS_CPP_TEXT "#include \"../embed_data/${filename_no_ext}.glsl.h\"\n")
1063-
string(APPEND SHADERMAP_TEXT "\t{ \"${filename_no_ext}.glsl\", ")
1064-
string(APPEND SHADERMAP_TEXT "std::string(reinterpret_cast<const char *>( ${filename_no_ext}_glsl ), ")
1065-
string(APPEND SHADERMAP_TEXT "sizeof( ${filename_no_ext}_glsl )) },\n")
1066-
endforeach()
1066+
string(APPEND SHADERS_CPP_TEXT "#include \"../embed_data/${filename_no_ext}.glsl.h\"\n")
1067+
string(APPEND SHADERMAP_TEXT "\t{ \"${filename_no_ext}.glsl\", ")
1068+
string(APPEND SHADERMAP_TEXT "std::string(reinterpret_cast<const char *>( ${filename_no_ext}_glsl ), ")
1069+
string(APPEND SHADERMAP_TEXT "sizeof( ${filename_no_ext}_glsl )) },\n")
1070+
endforeach()
10671071

1068-
string(APPEND SHADERS_CPP_TEXT "\nextern const std::unordered_map<std::string, std::string> shadermap\n{\n")
1069-
string(APPEND SHADERS_CPP_TEXT "${SHADERMAP_TEXT}")
1070-
string(APPEND SHADERS_CPP_TEXT "};\n")
1072+
string(APPEND SHADERS_CPP_TEXT "\nextern const std::unordered_map<std::string, std::string> shadermap\n{\n")
1073+
string(APPEND SHADERS_CPP_TEXT "${SHADERMAP_TEXT}")
1074+
string(APPEND SHADERS_CPP_TEXT "};\n")
10711075

1072-
daemon_write_generated("shaders.cpp" "${SHADERS_CPP_TEXT}")
1076+
daemon_write_generated("shaders.cpp" "${SHADERS_CPP_TEXT}")
1077+
endif()
10731078
endif()
10741079

10751080
if (BUILD_SERVER)

cmake/DaemonEmbed.cmake

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
# ===========================================================================
2+
#
3+
# Daemon BSD Source Code
4+
# Copyright (c) 2025 Daemon Developers
5+
# All rights reserved.
6+
#
7+
# This file is part of the Daemon BSD Source Code (Daemon Source Code).
8+
#
9+
# Redistribution and use in source and binary forms, with or without
10+
# modification, are permitted provided that the following conditions are met:
11+
# * Redistributions of source code must retain the above copyright
12+
# notice, this list of conditions and the following disclaimer.
13+
# * Redistributions in binary form must reproduce the above copyright
14+
# notice, this list of conditions and the following disclaimer in the
15+
# documentation and/or other materials provided with the distribution.
16+
# * Neither the name of the Daemon developers nor the
17+
# names of its contributors may be used to endorse or promote products
18+
# derived from this software without specific prior written permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
24+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
#
31+
# ===========================================================================
32+
33+
function(GenerateEmbedFile srcPath dstPath filename_symbol format target mode srcList headerList baseName filename)
34+
add_custom_command(
35+
OUTPUT ${dstPath}
36+
COMMAND ${CMAKE_COMMAND}
37+
"-DINPUT_FILE=${srcPath}"
38+
"-DOUTPUT_FILE=${dstPath}"
39+
"-DFILE_FORMAT=${format}"
40+
"-DVARIABLE_NAME=${filename_symbol}"
41+
"-DEMBED_MODE=${mode}"
42+
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake"
43+
MAIN_DEPENDENCY ${srcPath}
44+
)
45+
46+
target_sources(${target} PRIVATE ${dstPath})
47+
48+
string(APPEND srcList
49+
"#include \"${baseName}/${filename_symbol}.h\"\n")
50+
string(APPEND headerList
51+
"\t{ \"${filename}\", "
52+
"std::string(reinterpret_cast<const char *>( ${filename_symbol} ), "
53+
"sizeof( ${filename_symbol} )) },\n")
54+
endfunction()
55+
56+
function(GenerateEmbedFileH srcPaths dstPath format target)
57+
set(first TRUE)
58+
foreach(srcPath IN LISTS srcPaths)
59+
get_filename_component(filename "${srcPath}" NAME_WE)
60+
61+
if(first)
62+
set(mode WRITE)
63+
set(first FALSE)
64+
else()
65+
set(mode APPEND)
66+
endif()
67+
68+
set(cmd ${CMAKE_COMMAND}
69+
"-DINPUT_FILE=${srcPath}"
70+
"-DOUTPUT_FILE=${dstPath}"
71+
"-DFILE_FORMAT=${format}"
72+
"-DVARIABLE_NAME=${filename}"
73+
"-DEMBED_MODE=${mode}"
74+
-P "${CMAKE_CURRENT_SOURCE_DIR}/cmake/EmbedText.cmake" )
75+
list(APPEND cmdList ${cmd})
76+
endforeach()
77+
78+
add_custom_command(
79+
OUTPUT ${dstPath}
80+
COMMAND ${cmdList}
81+
MAIN_DEPENDENCY ${srcPath}
82+
)
83+
84+
target_sources(${target} PRIVATE ${dstPath})
85+
endfunction()
86+
87+
macro(daemon_embed_files BASENAME SLUG FORMAT TARGETNAME)
88+
set(EMBED_SOURCE_DIR "${SLUG}_EMBED_DIR")
89+
set(EMBED_SOURCE_LIST "${SLUG}_EMBED_LIST")
90+
91+
set(EMBED_SUBDIR "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}")
92+
set(EMBED_DIR "${DAEMON_GENERATED_DIR}/${EMBED_SUBDIR}")
93+
94+
foreach(kind CPP H)
95+
set(EMBED_${kind}_FILE "${DAEMON_EMBEDDED_SUBDIR}/${BASENAME}${DAEMON_GENERATED_${kind}_EXT}")
96+
set(EMBED_${kind}_TEXT "${DAEMON_GENERATED_HEADER}")
97+
endforeach()
98+
99+
string(APPEND EMBED_CPP_TEXT "#include \"${EMBED_H_FILE}\"\n\n")
100+
101+
set(EMBED_MAP_TEXT "")
102+
103+
foreach(filename ${${EMBED_SOURCE_LIST}})
104+
string(REPLACE "/" "_" filename_symbol "${filename}")
105+
string(REPLACE "." "_" filename_symbol "${filename_symbol}")
106+
107+
set(inpath "${${EMBED_SOURCE_DIR}}/${filename}")
108+
set(outpath "${EMBED_DIR}/${filename_symbol}${DAEMON_GENERATED_H_EXT}")
109+
110+
GenerateEmbedFile(${inpath} ${outpath} ${filename_symbol} ${FORMAT} ${TARGETNAME} WRITE ${EMBED_CPP_TEXT} ${EMBED_MAP_TEXT} TRUE ${BASENAME} ${filename})
111+
endforeach()
112+
113+
string(APPEND EMBED_CPP_TEXT
114+
"\n"
115+
"namespace ${BASENAME} {\n"
116+
"const std::unordered_map<std::string, std::string> FileMap\n{\n"
117+
"${EMBED_MAP_TEXT}\n"
118+
"};\n"
119+
"\n"
120+
"bool HasFile(Str::StringRef filename)\n"
121+
"{\n"
122+
"\treturn FileMap.find(filename) != FileMap.end();\n"
123+
"}\n"
124+
"\n"
125+
"const std::string ReadFile(Str::StringRef filename)\n"
126+
"{\n"
127+
" auto it = FileMap.find(filename);\n"
128+
" if (it != FileMap.end())\n"
129+
" return it->second;\n"
130+
" return \"\";\n"
131+
"}\n"
132+
"}"
133+
)
134+
135+
string(APPEND EMBED_H_TEXT
136+
"#include \"common/Common.h\"\n"
137+
"\n"
138+
"namespace ${BASENAME} {\n"
139+
"extern const std::unordered_map<std::string, std::string> FileMap;\n"
140+
"bool HasFile(Str::StringRef filename);\n"
141+
"const std::string ReadFile(Str::StringRef filename);\n"
142+
"};\n"
143+
)
144+
145+
foreach(kind CPP H)
146+
daemon_write_generated("${EMBED_${kind}_FILE}" "${EMBED_${kind}_TEXT}")
147+
endforeach()
148+
endmacro()

cmake/DaemonVulkan.cmake

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# ===========================================================================
2+
#
3+
# Daemon BSD Source Code
4+
# Copyright (c) 2025 Daemon Developers
5+
# All rights reserved.
6+
#
7+
# This file is part of the Daemon BSD Source Code (Daemon Source Code).
8+
#
9+
# Redistribution and use in source and binary forms, with or without
10+
# modification, are permitted provided that the following conditions are met:
11+
# * Redistributions of source code must retain the above copyright
12+
# notice, this list of conditions and the following disclaimer.
13+
# * Redistributions in binary form must reproduce the above copyright
14+
# notice, this list of conditions and the following disclaimer in the
15+
# documentation and/or other materials provided with the distribution.
16+
# * Neither the name of the Daemon developers nor the
17+
# names of its contributors may be used to endorse or promote products
18+
# derived from this software without specific prior written permission.
19+
#
20+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
21+
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
# DISCLAIMED. IN NO EVENT SHALL DAEMON DEVELOPERS BE LIABLE FOR ANY
24+
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
#
31+
# ===========================================================================
32+
33+
option( VULKAN_SPIRV_OUT "Output text SPIR-V files alongside the binary format." ON )
34+
option( VULKAN_SPIRV_OPTIMISE "Enable SPIR-V optimisations." ON )
35+
option( VULKAN_SPIRV_LTO "Enable link-time SPIR-V optimisations." ON )
36+
37+
if( USE_VULKAN )
38+
add_executable( VulkanShaderParser "${DAEMON_DIR}/cmake/DaemonVulkan/VulkanShaderParser.cpp" )
39+
40+
set( GRAPHICS_ENGINE_PATH ${DAEMON_DIR}/src/engine/renderer-vulkan/GraphicsEngine/ )
41+
set( GRAPHICS_ENGINE_PROCESSED_PATH ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/ )
42+
target_compile_definitions( VulkanShaderParser PRIVATE "-DDAEMON_VULKAN_GRAPHICS_ENGINE_PATH=\"${GRAPHICS_ENGINE_PATH}\"" )
43+
target_compile_definitions( VulkanShaderParser PRIVATE "-DDAEMON_VULKAN_GRAPHICS_ENGINE_PROCESSED_PATH=\"${GRAPHICS_ENGINE_PROCESSED_PATH}\"" )
44+
45+
file( MAKE_DIRECTORY ${GRAPHICS_ENGINE_PROCESSED_PATH} )
46+
47+
file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/processed/ )
48+
file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/ )
49+
file( MAKE_DIRECTORY ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/ )
50+
51+
set( VULKAN_SPIRV_DEBUG "default" CACHE STRING "glslangValidator debug options (remove: g0, non-semantic: gV)")
52+
set_property( CACHE VULKAN_SPIRV_DEBUG PROPERTY STRINGS default remove non-semantic )
53+
endif()
54+
55+
include( DaemonEmbed )
56+
57+
macro( GenerateVulkanShaders target )
58+
# Pre-processing for #insert/#include
59+
foreach( src IN LISTS graphicsEngineList )
60+
set( graphicsProcessedList ${graphicsProcessedList} ${src} )
61+
list( APPEND graphicsEngineOutputList ${GRAPHICS_ENGINE_PROCESSED_PATH}processed/${src} )
62+
63+
get_filename_component( name "${src}" NAME_WE )
64+
65+
if( VULKAN_SPIRV_OUT )
66+
set( spirvAsmPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/${name}.spirv )
67+
endif()
68+
69+
set( spirvBinPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/${name}.spirvBin )
70+
71+
list( APPEND graphicsEngineOutputList ${spirvAsmPath} )
72+
list( APPEND graphicsEngineOutputList ${spirvBinPath} )
73+
endforeach()
74+
75+
list( APPEND graphicsEngineOutputList ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/spirv.h )
76+
77+
# glslangValidator
78+
find_program( glslangV glslangValidator HINTS /usr/bin /usr/local/bin $ENV{VULKAN_SDK}/Bin/ $ENV{VULKAN_SDK}/Bin32/ )
79+
80+
if( glslangV STREQUAL "glslangValidator-NOTFOUND" )
81+
message( FATAL_ERROR "glslangValidator not found; make sure you have the Vulkan SDK installed" )
82+
endif()
83+
84+
set( spirvOptions --target-env vulkan1.3 --glsl-version 460 -e main -l -t )
85+
86+
if( VULKAN_SPIRV_OUT )
87+
set( spirvOut "ON" )
88+
else()
89+
set( spirvOut "OFF" )
90+
endif()
91+
92+
if( NOT VULKAN_SPIRV_OPTIMISE )
93+
set( spirvOptions ${spirvOptions} -Od )
94+
endif()
95+
96+
if( VULKAN_SPIRV_LTO )
97+
set( spirvOptions ${spirvOptions} --lto )
98+
endif()
99+
100+
if( VULKAN_SPIRV_DEBUG STREQUAL "remove" )
101+
set( spirvOptions ${spirvOptions} -g0 )
102+
elseif( VULKAN_SPIRV_DEBUG STREQUAL "non-semantic" )
103+
set( spirvOptions ${spirvOptions} -gV )
104+
endif()
105+
106+
add_custom_command(
107+
COMMAND VulkanShaderParser \"${glslangV} ${spirvOptions}\" ${spirvOut} ${graphicsProcessedList}
108+
DEPENDS ${graphicsEngineIDEList}
109+
OUTPUT ${graphicsEngineOutputList}
110+
COMMENT "Generating Vulkan graphics engine: ${graphicsProcessedList}"
111+
)
112+
113+
add_custom_target( VulkanShaderParserTarget ALL
114+
DEPENDS ${graphicsEngineOutputList}
115+
)
116+
117+
# file( STRINGS ${GRAPHICS_ENGINE_PROCESSED_PATH}ShaderStages stagesList )
118+
119+
foreach( src IN LISTS graphicsEngineList )
120+
set( srcPath ${GRAPHICS_ENGINE_PROCESSED_PATH}processed/${src} )
121+
122+
get_filename_component( name "${src}" NAME_WE )
123+
124+
set( spirvAsmPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/${name}.spirv )
125+
126+
set( spirvBinPath ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/bin/${name}.spirvBin )
127+
128+
list( POP_FRONT stagesList stage )
129+
130+
#add_custom_command(
131+
# OUTPUT ${spirvBinPath}
132+
# COMMAND ${glslangV} ${spirvOptions} -S ${stage} -V ${srcPath} -o ${spirvBinPath} -H > ${spirvAsmPath}
133+
# DEPENDS ${srcPath}
134+
# COMMENT "Generating Vulkan graphics engine binaries: ${src}"
135+
#)
136+
137+
list( APPEND spirvBinList ${spirvBinPath} )
138+
endforeach()
139+
140+
GenerateEmbedFileH( "${spirvBinList}" ${DAEMON_GENERATED_DIR}/DaemonVulkan/GraphicsEngine/spirv/spirv.h BINARY client-objects )
141+
142+
add_custom_target( VulkanShaderBin ALL
143+
DEPENDS ${spirvBinList}
144+
)
145+
146+
target_sources( ${target} PRIVATE ${graphicsEngineOutputList} )
147+
endmacro()

0 commit comments

Comments
 (0)