cmake_minimum_required (VERSION 3.29) project(VulkanEngine) list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake") include(BuildInfo) include(FetchContent) #LTO include(CheckIPOSupported) check_ipo_supported(RESULT LTO_SUPPORTED OUTPUT LTO_ERROR) set(CMAKE_EXPORT_COMPILE_COMMANDS ON) if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") find_program(GCC_AR NAMES gcc-ar REQUIRED) find_program(GCC_RANLIB NAMES gcc-ranlib REQUIRED) set(CMAKE_AR "${GCC_AR}") set(CMAKE_RANLIB "${GCC_RANLIB}") endif() # Find all package dependencies find_package( glfw3 REQUIRED ) find_package( glm REQUIRED ) find_package( VulkanMemoryAllocator CONFIG REQUIRED ) find_package( fmt REQUIRED ) # Shader compilers add_executable (glslang::validator IMPORTED) find_program (GLSLANG_VALIDATOR "glslangValidator" HINTS $ENV{VULKAN_SDK}/bin REQUIRED) set_property (TARGET glslang::validator PROPERTY IMPORTED_LOCATION "${GLSLANG_VALIDATOR}") find_program(SLANGC_EXECUTABLE slangc HINTS $ENV{VULKAN_SDK}/bin REQUIRED) # fastgltf because it's not in nixpkgs FetchContent_Declare( fastgltf GIT_REPOSITORY https://github.com/spnda/fastgltf.git GIT_TAG v0.8.0 ) FetchContent_MakeAvailable(fastgltf) # vk-bootstrap because CMAKE can't find it on NixOS FetchContent_Declare( vk-bootstrap GIT_REPOSITORY https://github.com/charles-lunarg/vk-bootstrap.git GIT_TAG v1.3.295 ) FetchContent_MakeAvailable(vk-bootstrap) # Helper functions to build shaders function(addGlslShader SOURCE OUTPUT_DIR) get_filename_component(SHADER_NAME ${SOURCE} NAME_WE) set(SPV_FILE "${OUTPUT_DIR}/${SHADER_NAME}.spv") add_custom_command( OUTPUT ${SPV_FILE} COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR} COMMAND glslang::validator -V --target-env vulkan1.4 # Change if needed -o ${SPV_FILE} ${SOURCE} DEPENDS ${SOURCE} COMMENT "Compiling GLSL shader: ${SOURCE} -> ${SPV_FILE}" VERBATIM ) set(SPV_FILE ${SPV_FILE} PARENT_SCOPE) endfunction() function(addSlangShader SOURCES ENTRY_POINTS OUTPUT_DIR) set(SPV_FILE "${OUTPUT_DIR}/slang.spv") add_custom_command( OUTPUT ${SPV_FILE} COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTPUT_DIR} COMMAND ${SLANGC_EXECUTABLE} ${SOURCES} -target spirv -profile spirv_1_6+spvRayQueryKHR # Change if needed -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o ${SPV_FILE} DEPENDS ${SOURCES} COMMENT "Compiling Slang shaders -> ${SPV_FILE}" VERBATIM ) set(SPV_FILE ${SPV_FILE} PARENT_SCOPE) endfunction() # A function to automate executables aditions function ( addBinary BINARY_NAME ) cmake_parse_arguments ( BINARY "IMGUI;LICENSE" "SOURCE" "SHADERS;SLANG_SHADERS;LIBS;TEXTURES;MODELS" ${ARGN} ) if (DEFINED BINARY_SOURCE) add_executable ( ${BINARY_NAME} src/${BINARY_SOURCE}.cpp ) endif() target_include_directories( ${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src ) # Sets the output dir to have clear separation between binaries set_target_properties ( ${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${BINARY_NAME} ) set_target_properties ( ${BINARY_NAME} PROPERTIES CXX_STANDARD 20 ) # Uses C++20 # Sets per binary LTO if(LTO_SUPPORTED AND CMAKE_BUILD_TYPE STREQUAL "Release") set_target_properties(${BINARY_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION TRUE) message("Enabled LTO") endif() set_target_properties(${BINARY_NAME} PROPERTIES CXX_SCAN_FOR_MODULES OFF) # Define VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS to treat VK_ERROR_OUT_OF_DATE_KHR as a success code target_compile_definitions ( ${BINARY_NAME} PRIVATE "VULKAN_HPP_HANDLE_ERROR_OUT_OF_DATE_AS_SUCCESS" $<$:DEBUG> # So CMAKE expose a #define DEBUG for debug builds # Exposes versions BUILD_ID="${ENGINE_VERSION}" ) if(BINARY_IMGUI) target_include_directories(${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/imgui ${CMAKE_SOURCE_DIR}/src/imgui/backends ) target_sources(${BINARY_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/imgui/imgui.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_draw.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_tables.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_widgets.cpp ${CMAKE_SOURCE_DIR}/src/imgui/imgui_demo.cpp #${CMAKE_SOURCE_DIR}/src/imgui/imgui_memory_editor.h ${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_glfw.cpp ${CMAKE_SOURCE_DIR}/src/imgui/backends/imgui_impl_vulkan.cpp ) endif() if(BINARY_LICENSE) file(COPY ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME}) endif() if(DEFINED BINARY_SHADERS) set(SHADER_OUTPUT_DIR ${CMAKE_BINARY_DIR}/${BINARY_NAME}/shaders) set(ALL_SPV_FILES "") set(EXPANDED_SHADERS "") foreach(SHADER_PATTERN ${BINARY_SHADERS}) if(SHADER_PATTERN MATCHES "[*?]") file(GLOB SHADER_FILES CONFIGURE_DEPENDS ${SHADER_PATTERN}) list(APPEND EXPANDED_SHADERS ${SHADER_FILES}) else() list(APPEND EXPANDED_SHADERS ${SHADER_PATTERN}) endif() endforeach() foreach(SHADER_SRC ${EXPANDED_SHADERS}) if(NOT IS_ABSOLUTE ${SHADER_SRC}) set(SHADER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_SRC}) endif() get_filename_component(EXT ${SHADER_SRC} EXT) if(EXT STREQUAL ".slang") addSlangShader(${SHADER_SRC} "${BINARY_SLANG_ENTRIES}" ${SHADER_OUTPUT_DIR}) list(APPEND ALL_SPV_FILES ${SPV_FILE}) else() addGlslShader(${SHADER_SRC} ${SHADER_OUTPUT_DIR}) list(APPEND ALL_SPV_FILES ${SPV_FILE}) endif() endforeach() add_custom_target(shaders_${BINARY_NAME} DEPENDS ${ALL_SPV_FILES}) add_dependencies(${BINARY_NAME} shaders_${BINARY_NAME}) endif() if (DEFINED BINARY_LIBS) target_link_libraries ( ${BINARY_NAME} ${BINARY_LIBS} ) endif() if (DEFINED BINARY_MODELS) # Adds the 3D models in the binary folder set(RESOLVED_MODELS "") foreach(MODEL_PATTERN ${BINARY_MODELS}) file(GLOB MATCHED_MODELS CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/assets/models/${MODEL_PATTERN}" ) list(APPEND RESOLVED_MODELS ${MATCHED_MODELS}) endforeach() if (RESOLVED_MODELS) file(COPY ${RESOLVED_MODELS} DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME}/models) endif() endif() if (DEFINED BINARY_TEXTURES) # Adds the textures in the binary folder set(RESOLVED_TEXTURES "") foreach(TEX_PATTERN ${BINARY_TEXTURES}) file(GLOB MATCHED_TEXTURES CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/assets/textures/${TEX_PATTERN}" ) list(APPEND RESOLVED_TEXTURES ${MATCHED_TEXTURES}) endforeach() if (RESOLVED_TEXTURES) file(COPY ${RESOLVED_TEXTURES} DESTINATION ${CMAKE_BINARY_DIR}/${BINARY_NAME}/textures) endif() endif () endfunction() # Scan the shader folder file(GLOB SHADER_SOURCES CONFIGURE_DEPENDS "shaders/*") # Adds the main binary addBinary ( engine SOURCE Engine/main SHADERS ${SHADER_SOURCES} SHADERS LIBS glfw fmt vk-bootstrap vulkan IMGUI LICENSE ) addBinary ( server SOURCE Server/main )