diff --git a/CMakeLists.txt b/CMakeLists.txt index 817a21d..361ccc8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,28 @@ -cmake_minimum_required (VERSION 3.8) +cmake_minimum_required(VERSION 3.16) -project ("vulkan_engine") +project(vulkan_engine LANGUAGES C CXX) -if (WIN32) - set(VULKAN_SDK "$ENV{VULKAN_SDK}") - set(Vulkan_INCLUDE_DIR "C:/VulkanSDK/1.3.296.0/Include") - set(Vulkan_LIBRARY "C:/VulkanSDK/1.3.296.0/Lib/vulkan-1.lib") +if(WIN32) + if(DEFINED ENV{VULKAN_SDK}) + file(TO_CMAKE_PATH "$ENV{VULKAN_SDK}" _VULKAN_SDK) + set(Vulkan_INCLUDE_DIR "${_VULKAN_SDK}/Include") + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(Vulkan_LIBRARY "${_VULKAN_SDK}/Lib/vulkan-1.lib") + else() + set(Vulkan_LIBRARY "${_VULKAN_SDK}/Lib32/vulkan-1.lib") + endif() + elseif(EXISTS "C:/VulkanSDK/1.3.296.0/Include") + # Fallback for a common SDK install path; update if your SDK version differs. + set(Vulkan_INCLUDE_DIR "C:/VulkanSDK/1.3.296.0/Include") + set(Vulkan_LIBRARY "C:/VulkanSDK/1.3.296.0/Lib/vulkan-1.lib") + endif() endif() -find_package(Vulkan REQUIRED) +find_package(Vulkan REQUIRED COMPONENTS glslangValidator) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") # Third-party deps are vendored; keep builds offline-friendly by default. # BVH2's CMake enables tests by default, which would FetchContent googletest. @@ -16,44 +30,46 @@ set(BVH2_ENABLE_TESTS OFF CACHE BOOL "Disable BVH2 tests (offline builds)" FORCE add_subdirectory(third_party) -if (MSVC AND CMAKE_C_COMPILER_ID MATCHES "Clang") - if (TARGET SDL2) - target_link_options(SDL2 PRIVATE /DEFAULTLIB:ucrt.lib /DEFAULTLIB:vcruntime.lib) - endif() - if (TARGET SDL2-static) - target_link_options(SDL2-static PRIVATE /DEFAULTLIB:ucrt.lib /DEFAULTLIB:vcruntime.lib) - endif() +if(MSVC AND CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND CMAKE_CXX_SIMULATE_ID STREQUAL "MSVC") + foreach(_SDL_TARGET IN ITEMS SDL2 SDL2-static) + if(TARGET ${_SDL_TARGET}) + target_link_options(${_SDL_TARGET} PRIVATE /DEFAULTLIB:ucrt.lib /DEFAULTLIB:vcruntime.lib) + endif() + endforeach() endif() -set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") -set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin") - add_subdirectory(src) -find_program(GLSL_VALIDATOR glslangValidator HINTS /usr/bin /usr/local/bin $ENV{VULKAN_SDK}/Bin/ $ENV{VULKAN_SDK}/Bin32/) +option(VULKAN_ENGINE_BUILD_SHADERS "Compile GLSL shaders to SPIR-V at build time" ON) +if(VULKAN_ENGINE_BUILD_SHADERS) + set(GLSL_VALIDATOR "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}") + if(NOT GLSL_VALIDATOR) + find_program(GLSL_VALIDATOR glslangValidator HINTS /usr/bin /usr/local/bin) + endif() + if(NOT GLSL_VALIDATOR) + message(FATAL_ERROR "glslangValidator not found. Install the Vulkan SDK or disable shader compilation with -DVULKAN_ENGINE_BUILD_SHADERS=OFF.") + endif() - -file(GLOB_RECURSE GLSL_SOURCE_FILES - "${PROJECT_SOURCE_DIR}/shaders/*.frag" - "${PROJECT_SOURCE_DIR}/shaders/*.vert" - "${PROJECT_SOURCE_DIR}/shaders/*.comp" + file(GLOB_RECURSE GLSL_SOURCE_FILES CONFIGURE_DEPENDS + "${PROJECT_SOURCE_DIR}/shaders/*.frag" + "${PROJECT_SOURCE_DIR}/shaders/*.vert" + "${PROJECT_SOURCE_DIR}/shaders/*.comp" ) -foreach(GLSL ${GLSL_SOURCE_FILES}) - message(STATUS "BUILDING SHADER") - get_filename_component(FILE_NAME ${GLSL} NAME) - set(SPIRV "${PROJECT_SOURCE_DIR}/shaders/${FILE_NAME}.spv") - message(STATUS ${GLSL}) - add_custom_command( - OUTPUT ${SPIRV} - COMMAND ${GLSL_VALIDATOR} -V --target-env vulkan1.2 ${GLSL} -o ${SPIRV} - DEPENDS ${GLSL}) - list(APPEND SPIRV_BINARY_FILES ${SPIRV}) -endforeach(GLSL) + set(SPIRV_BINARY_FILES "") + foreach(GLSL IN LISTS GLSL_SOURCE_FILES) + set(SPIRV "${GLSL}.spv") + add_custom_command( + OUTPUT "${SPIRV}" + COMMAND "${GLSL_VALIDATOR}" -V --target-env vulkan1.2 "${GLSL}" -o "${SPIRV}" + DEPENDS "${GLSL}" + VERBATIM + ) + list(APPEND SPIRV_BINARY_FILES "${SPIRV}") + endforeach() -add_custom_target(shaders_spirv DEPENDS ${SPIRV_BINARY_FILES}) - -# Ensure shaders are built alongside the executable. -add_dependencies(vulkan_engine shaders_spirv) + add_custom_target(shaders_spirv DEPENDS ${SPIRV_BINARY_FILES}) + add_dependencies(vulkan_engine shaders_spirv) +endif() diff --git a/docs/BUILD.md b/docs/BUILD.md index 16956d3..2f3ba0d 100644 --- a/docs/BUILD.md +++ b/docs/BUILD.md @@ -2,7 +2,7 @@ - Prerequisites - Vulkan SDK installed and `VULKAN_SDK` set. - - A C++20 compiler and CMake ≥ 3.8. + - A C++20 compiler and CMake ≥ 3.16. - GPU drivers with Vulkan 1.2+. - KTX software with libktx diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 978dd27..2b16f5e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -195,7 +195,7 @@ if (CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDeb /OPT:ICF ) # Optional: AVX2 - # target_compile_options(vulkan_engine PRIVATE /arch:AVX2) + target_compile_options(vulkan_engine PRIVATE /arch:AVX2) elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") # GCC (g++) @@ -311,23 +311,73 @@ target_include_directories(vma_impl PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../thir target_link_libraries(vma_impl PRIVATE Vulkan::Vulkan) target_link_libraries(vulkan_engine PUBLIC $) -target_precompile_headers(vulkan_engine PUBLIC ) +target_precompile_headers(vulkan_engine PRIVATE + + + + + + + + +) -add_custom_command(TARGET vulkan_engine POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ $ - COMMAND_EXPAND_LISTS - ) +if(WIN32) + if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.21) + add_custom_command(TARGET vulkan_engine POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $ $ + COMMAND_EXPAND_LISTS + ) + else() + message(WARNING "CMake < 3.21: skipping runtime DLL copy step for vulkan_engine") + endif() +endif() -find_package(ktx CONFIG REQUIRED) -set(_KTX_TARGET "") -if (TARGET ktx::ktx) - set(_KTX_TARGET ktx::ktx) -elseif (TARGET KTX::ktx) - set(_KTX_TARGET KTX::ktx) -elseif (TARGET ktx) - set(_KTX_TARGET ktx) +# KTX (libktx) +# NOTE: Under WSL it's easy to accidentally pick up the Windows KTX package (ktx.dll), +# which will configure but fail to link on Linux. Prefer the native library when needed. +find_package(ktx CONFIG QUIET) + +set(_KTX_CMAKE_TARGET "") +if(TARGET ktx::ktx) + set(_KTX_CMAKE_TARGET ktx::ktx) +elseif(TARGET KTX::ktx) + set(_KTX_CMAKE_TARGET KTX::ktx) +elseif(TARGET ktx) + set(_KTX_CMAKE_TARGET ktx) endif() -if (_KTX_TARGET STREQUAL "") - message(FATAL_ERROR "libktx not found; please install KTX v2 and expose its CMake package") + +set(_KTX_USE_FALLBACK OFF) +if(_KTX_CMAKE_TARGET STREQUAL "") + set(_KTX_USE_FALLBACK ON) +else() + get_target_property(_KTX_IMPORTED "${_KTX_CMAKE_TARGET}" IMPORTED) + if(_KTX_IMPORTED) + set(_KTX_IMPORTED_LOCATION "") + get_target_property(_KTX_IMPORTED_LOCATION "${_KTX_CMAKE_TARGET}" IMPORTED_LOCATION) + if(NOT _KTX_IMPORTED_LOCATION) + get_target_property(_KTX_IMPORTED_LOCATION "${_KTX_CMAKE_TARGET}" IMPORTED_LOCATION_RELEASE) + endif() + if(NOT _KTX_IMPORTED_LOCATION) + get_target_property(_KTX_IMPORTED_LOCATION "${_KTX_CMAKE_TARGET}" IMPORTED_LOCATION_DEBUG) + endif() + + if(NOT _KTX_IMPORTED_LOCATION) + set(_KTX_USE_FALLBACK ON) + elseif(NOT WIN32 AND _KTX_IMPORTED_LOCATION MATCHES "\\.dll$|\\.lib$") + set(_KTX_USE_FALLBACK ON) + endif() + endif() +endif() + +if(_KTX_USE_FALLBACK) + find_path(KTX_INCLUDE_DIR NAMES ktx.h) + find_library(KTX_LIBRARY NAMES ktx) + if(NOT KTX_INCLUDE_DIR OR NOT KTX_LIBRARY) + message(FATAL_ERROR "libktx not found; please install KTX v2 and make it discoverable via ktx_DIR or CMAKE_PREFIX_PATH") + endif() + target_include_directories(vulkan_engine PUBLIC "${KTX_INCLUDE_DIR}") + target_link_libraries(vulkan_engine PUBLIC "${KTX_LIBRARY}") +else() + target_link_libraries(vulkan_engine PUBLIC "${_KTX_CMAKE_TARGET}") endif() -target_link_libraries(vulkan_engine PUBLIC ${_KTX_TARGET}) diff --git a/third_party/CMakeLists.txt b/third_party/CMakeLists.txt index ff13c2f..eb4382f 100644 --- a/third_party/CMakeLists.txt +++ b/third_party/CMakeLists.txt @@ -1,5 +1,3 @@ -find_package(Vulkan REQUIRED) - add_library(vkbootstrap STATIC) add_library(glm INTERFACE) add_library(vma INTERFACE) @@ -62,11 +60,6 @@ target_include_directories(ImGuizmo PUBLIC imgui ) -target_compile_definitions(ImGuizmo - PRIVATE - IMGUI_DEFINE_MATH_OPERATORS -) - target_link_libraries(ImGuizmo PUBLIC imgui) add_subdirectory(BVH)