# Compile GLSL (.comp/.vert/.frag) into SPIR-V at build time. # # Usage: # simv_compile_shaders(simv_shaders # shaders/editor/mesh.vert # shaders/editor/mesh.frag # INCLUDES shaders # ) # # Produces ${CMAKE_BINARY_DIR}/spirv//.spv as a custom target. function(simv_compile_shaders TARGET) cmake_parse_arguments(SCS "" "" "INCLUDES" ${ARGN}) set(SOURCES ${SCS_UNPARSED_ARGUMENTS}) set(SPIRV_OUT_DIR "${CMAKE_BINARY_DIR}/spirv") file(MAKE_DIRECTORY "${SPIRV_OUT_DIR}") set(SPV_OUTPUTS "") foreach(SRC IN LISTS SOURCES) get_filename_component(SHADER_NAME "${SRC}" NAME) file(RELATIVE_PATH REL_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${SRC}") get_filename_component(REL_DIR "${REL_PATH}" DIRECTORY) set(OUT_PATH "${SPIRV_OUT_DIR}/${REL_DIR}/${SHADER_NAME}.spv") get_filename_component(OUT_DIR "${OUT_PATH}" DIRECTORY) file(MAKE_DIRECTORY "${OUT_DIR}") set(INCLUDE_FLAGS "") foreach(INC IN LISTS SCS_INCLUDES) # glslangValidator requires -I with NO whitespace. list(APPEND INCLUDE_FLAGS "-I${INC}") endforeach() add_custom_command( OUTPUT "${OUT_PATH}" COMMAND "${Vulkan_GLSLANG_VALIDATOR_EXECUTABLE}" -V --target-env vulkan1.3 ${INCLUDE_FLAGS} -o "${OUT_PATH}" "${SRC}" DEPENDS "${SRC}" COMMENT "GLSL → SPIR-V: ${REL_PATH}" VERBATIM ) list(APPEND SPV_OUTPUTS "${OUT_PATH}") endforeach() add_custom_target(${TARGET} ALL DEPENDS ${SPV_OUTPUTS}) set_target_properties(${TARGET} PROPERTIES SIMV_SPIRV_DIR "${SPIRV_OUT_DIR}" ) endfunction()