Files
vulkan-tutorial/CMakeLists.txt
2025-12-22 03:28:25 +00:00

325 lines
10 KiB
CMake

cmake_minimum_required (VERSION 3.29)
project (VulkanTutorial)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")
# Add option to enable/disable C++ 20 module
option(ENABLE_CPP20_MODULE "Enable C++ 20 module support for Vulkan" OFF)
# Enable C++ module dependency scanning only if C++ 20 module is enabled
if(ENABLE_CPP20_MODULE)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)
endif()
find_package (glfw3 REQUIRED)
find_package (glm REQUIRED)
find_package (Vulkan REQUIRED)
find_package (tinyobjloader REQUIRED)
find_package (tinygltf REQUIRED)
find_package (KTX REQUIRED)
# set up Vulkan C++ module only if enabled
if(ENABLE_CPP20_MODULE)
add_library(VulkanCppModule)
add_library(Vulkan::cppm ALIAS VulkanCppModule)
target_compile_definitions(VulkanCppModule
PUBLIC VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
)
target_include_directories(VulkanCppModule
PUBLIC
"${Vulkan_INCLUDE_DIR}"
)
target_link_libraries(VulkanCppModule
PUBLIC
Vulkan::Vulkan
)
set_target_properties(VulkanCppModule PROPERTIES CXX_STANDARD 20)
# Add MSVC-specific compiler options for proper C++ module support
if(MSVC)
target_compile_options(VulkanCppModule PRIVATE
/std:c++latest # Use latest C++ standard for better module support
/permissive- # Standards conformance mode
/Zc:__cplusplus # Enable correct __cplusplus macro
/EHsc # Enable C++ exception handling
/Zc:preprocessor # Use conforming preprocessor
/translateInclude # Automatically translate #include to import for standard library
)
endif()
target_sources(VulkanCppModule
PUBLIC
FILE_SET cxx_modules TYPE CXX_MODULES
BASE_DIRS
"${Vulkan_INCLUDE_DIR}"
FILES
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
)
# Add the vulkan.cppm file directly as a source file
target_sources(VulkanCppModule
PRIVATE
"${Vulkan_INCLUDE_DIR}/vulkan/vulkan.cppm"
)
else()
# Create a dummy interface library when C++ 20 module is disabled
add_library(VulkanCppModule INTERFACE)
add_library(Vulkan::cppm ALIAS VulkanCppModule)
target_link_libraries(VulkanCppModule INTERFACE Vulkan::Vulkan)
target_compile_definitions(VulkanCppModule
INTERFACE VULKAN_HPP_DISPATCH_LOADER_DYNAMIC=1 VULKAN_HPP_NO_STRUCT_CONSTRUCTORS=1
)
endif()
find_package(stb REQUIRED)
set(STB_INCLUDEDIR ${stb_INCLUDE_DIRS})
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)
function (add_shaders_target TARGET)
cmake_parse_arguments ("SHADER" "" "CHAPTER_NAME" "SOURCES" ${ARGN})
set (SHADERS_DIR shaders)
add_custom_command (
OUTPUT ${SHADERS_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR}
)
add_custom_command (
OUTPUT ${SHADERS_DIR}/frag.spv ${SHADERS_DIR}/vert.spv
COMMAND glslang::validator
ARGS --target-env vulkan1.0 ${SHADER_SOURCES} --quiet
WORKING_DIRECTORY ${SHADERS_DIR}
DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES}
COMMENT "Compiling Shaders"
VERBATIM
)
add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/frag.spv ${SHADERS_DIR}/vert.spv)
endfunction ()
function (add_slang_shader_target TARGET)
cmake_parse_arguments ("SHADER" "" "CHAPTER_NAME" "SOURCES" ${ARGN})
set (SHADERS_DIR ${CHAPTER_NAME}/shaders)
file(GLOB HAS_COMPUTE shaders/${CHAPTER_SHADER}.comp)
set (ENTRY_POINTS -entry vertMain -entry fragMain)
if(HAS_COMPUTE)
list(APPEND ENTRY_POINTS -entry compMain)
endif()
add_custom_command (
OUTPUT ${SHADERS_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${SHADERS_DIR}
)
add_custom_command (
OUTPUT ${SHADERS_DIR}/${CHAPTER_SHADER}.spv
COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o ${CHAPTER_SHADER}.spv
WORKING_DIRECTORY ${SHADERS_DIR}
DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES}
COMMENT "Compiling Slang Shaders"
VERBATIM
)
add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/${CHAPTER_SHADER}.spv)
endfunction()
function (add_chapter CHAPTER_NAME)
cmake_parse_arguments (CHAPTER "" "SHADER" "LIBS;TEXTURES;MODELS" ${ARGN})
add_executable (${CHAPTER_NAME} ${CHAPTER_NAME}.cpp)
set_target_properties (${CHAPTER_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CHAPTER_NAME})
set_target_properties (${CHAPTER_NAME} PROPERTIES CXX_STANDARD 20)
target_link_libraries (${CHAPTER_NAME} Vulkan::cppm glfw)
target_include_directories (${CHAPTER_NAME} PRIVATE ${STB_INCLUDEDIR})
# Add compile definition if C++ 20 module is enabled
if(ENABLE_CPP20_MODULE)
target_compile_definitions(${CHAPTER_NAME} PRIVATE USE_CPP20_MODULES=1)
endif()
if(WIN32)
if(${CMAKE_GENERATOR} MATCHES "Visual Studio.*")
set_target_properties(${CHAPTER_NAME} PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/${CHAPTER_NAME}")
endif()
endif()
if (DEFINED CHAPTER_SHADER)
set (CHAPTER_SHADER_TARGET ${CHAPTER_NAME}_shader)
file (GLOB SHADER_SOURCES shaders/${CHAPTER_SHADER}.frag shaders/${CHAPTER_SHADER}.vert shaders/${CHAPTER_SHADER}.comp)
if(SHADER_SOURCES)
add_shaders_target (${CHAPTER_SHADER_TARGET} CHAPTER_NAME ${CHAPTER_NAME} SOURCES ${SHADER_SOURCES})
add_dependencies (${CHAPTER_NAME} ${CHAPTER_SHADER_TARGET})
endif()
set (CHAPTER_SHADER_SLANG_TARGET ${CHAPTER_NAME}_slang_shader)
file (GLOB SHADER_SLANG_SOURCES shaders/${CHAPTER_SHADER}.slang)
if(SHADER_SLANG_SOURCES)
add_slang_shader_target( ${CHAPTER_SHADER_SLANG_TARGET} CHAPTER_NAME ${CHAPTER_NAME} SOURCES ${SHADER_SLANG_SOURCES})
add_dependencies(${CHAPTER_NAME} ${CHAPTER_SHADER_SLANG_TARGET})
endif()
endif ()
if (DEFINED CHAPTER_LIBS)
target_link_libraries (${CHAPTER_NAME} ${CHAPTER_LIBS})
endif ()
if (DEFINED CHAPTER_MODELS)
list(TRANSFORM CHAPTER_MODELS PREPEND "${CMAKE_SOURCE_DIR}/assets/")
file (COPY ${CHAPTER_MODELS} DESTINATION ${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/models)
endif ()
if (DEFINED CHAPTER_TEXTURES)
list(TRANSFORM CHAPTER_TEXTURES PREPEND "${CMAKE_SOURCE_DIR}/assets/")
file (COPY ${CHAPTER_TEXTURES} DESTINATION ${CMAKE_BINARY_DIR}/${CHAPTER_NAME}/textures)
endif ()
endfunction ()
add_chapter (00_base_code)
add_chapter (01_instance_creation)
add_chapter (02_validation_layers)
add_chapter (03_physical_device_selection)
add_chapter (04_logical_device)
add_chapter (05_window_surface)
add_chapter (06_swap_chain_creation)
add_chapter (07_image_views)
add_chapter (08_graphics_pipeline)
add_chapter (09_shader_modules
SHADER 09_shader_base)
add_chapter (10_fixed_functions
SHADER 09_shader_base)
add_chapter (12_graphics_pipeline_complete
SHADER 09_shader_base)
add_chapter (14_command_buffers
SHADER 09_shader_base)
add_chapter (15_hello_triangle
SHADER 09_shader_base)
add_chapter (16_frames_in_flight
SHADER 09_shader_base)
add_chapter (17_swap_chain_recreation
SHADER 09_shader_base)
add_chapter (18_vertex_input
SHADER 18_shader_vertexbuffer
LIBS glm::glm)
add_chapter (19_vertex_buffer
SHADER 18_shader_vertexbuffer
LIBS glm::glm)
add_chapter (20_staging_buffer
SHADER 18_shader_vertexbuffer
LIBS glm::glm)
add_chapter (21_index_buffer
SHADER 18_shader_vertexbuffer
LIBS glm::glm)
add_chapter (22_descriptor_layout
SHADER 22_shader_ubo
LIBS glm::glm)
add_chapter (23_descriptor_sets
SHADER 22_shader_ubo
LIBS glm::glm)
add_chapter (24_texture_image
SHADER 22_shader_ubo
TEXTURES images/texture.jpg
LIBS glm::glm)
add_chapter (25_sampler
SHADER 22_shader_ubo
TEXTURES images/texture.jpg
LIBS glm::glm)
add_chapter (26_texture_mapping
SHADER 26_shader_textures
TEXTURES images/texture.jpg
LIBS glm::glm)
add_chapter (27_depth_buffering
SHADER 27_shader_depth
TEXTURES images/texture.jpg
LIBS glm::glm)
# add_chapter (28_model_loading
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (29_mipmapping
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (30_multisampling
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (31_compute_shader
# SHADER 31_shader_compute
# LIBS glm::glm)
#
# add_chapter (32_ecosystem_utilities
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (33_vulkan_profiles
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (34_android
# SHADER 27_shader_depth
# MODELS viking_room.obj
# TEXTURES viking_room.png
# LIBS glm::glm tinyobjloader::tinyobjloader)
#
# add_chapter (35_gltf_ktx
# SHADER 27_shader_depth
# MODELS viking_room.glb
# TEXTURES viking_room.ktx2
# LIBS glm::glm tinygltf::tinygltf KTX::ktx)
#
# add_chapter (36_multiple_objects
# SHADER 27_shader_depth
# MODELS viking_room.glb
# TEXTURES viking_room.ktx2
# LIBS glm::glm tinygltf::tinygltf KTX::ktx)
#
# add_chapter (37_multithreading
# SHADER 37_shader_compute
# LIBS glm::glm)
#
# add_chapter (38_ray_tracing
# SHADER 38_ray_tracing
# MODELS plant_on_table.obj
# MODELS plant_on_table.mtl
# TEXTURES plant_on_table_textures/nettle_plant_diff_4k.png
# TEXTURES plant_on_table_textures/potted_plant_02_pot_diff_1k.png
# TEXTURES plant_on_table_textures/wooden_picnic_table_bottom_diff_1k.png
# TEXTURES plant_on_table_textures/wooden_picnic_table_top_diff_1k.png
# LIBS glm::glm tinyobjloader::tinyobjloader)