cmake_minimum_required (VERSION 3.29) project (VulkanTutorial) 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 ${SHADER_CHAPTER_NAME}/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 ${SHADER_CHAPTER_NAME}/shaders) file(GLOB HAS_COMPUTE ${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}/slang.spv COMMAND ${SLANGC_EXECUTABLE} ${SHADER_SOURCES} -target spirv -profile spirv_1_4+spvRayQueryKHR -emit-spirv-directly -fvk-use-entrypoint-name ${ENTRY_POINTS} -o slang.spv WORKING_DIRECTORY ${SHADERS_DIR} DEPENDS ${SHADERS_DIR} ${SHADER_SOURCES} COMMENT "Compiling Slang Shaders" VERBATIM ) add_custom_target (${TARGET} DEPENDS ${SHADERS_DIR}/slang.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 ${CHAPTER_SHADER}.frag ${CHAPTER_SHADER}.vert ${CHAPTER_SHADER}.comp) add_shaders_target (${CHAPTER_SHADER_TARGET} CHAPTER_NAME ${CHAPTER_NAME} SOURCES ${SHADER_SOURCES}) add_dependencies (${CHAPTER_NAME} ${CHAPTER_SHADER_TARGET}) set (CHAPTER_SHADER_SLANG_TARGET ${CHAPTER_NAME}_slang_shader) file (GLOB SHADER_SLANG_SOURCES ${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)