function(compile_glsl_by_shaderc) set(oneValueArgs DST VULKAN_TARGET DEPENDENCY) set(multiValueArgs SOURCE_FILES HEADER_FILES FLAGS) cmake_parse_arguments(COMPILE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) # Check if the GLSL compiler is present if(NOT GLSLC) message(ERROR "Could not find GLSLC to compile shaders") return() endif() # By default use Vulkan 1.1 if(NOT DEFINED COMPILE_VULKAN_TARGET) set(COMPILE_VULKAN_TARGET vulkan1.1) endif() # If destination is not present, same as source if(NOT DEFINED COMPILE_DST) message(ERROR " --- DST not defined") return() endif() # Make the output directory if needed file(MAKE_DIRECTORY ${COMPILE_DST}) # If no flag set -g (debug) if(NOT DEFINED COMPILE_FLAGS) set(COMPILE_FLAGS -g) endif() # Compiling all GLSL sources foreach(GLSL_SRC ${COMPILE_SOURCE_FILES}) # Find the dependency files for the GLSL source # or use all headers as dependencies. if(COMPILE_DEPENDENCY) get_glsl_dependencies(SRC ${GLSL_SRC} FLAGS ${COMPILE_FLAGS}) else() set(GLSL_DEPENDENCY ${HEADER_FILES}) endif() # Default compiler command, always adding debug information (Add and option to opt-out?) set(COMPILE_CMD ${COMPILE_FLAGS} --target-env=${COMPILE_VULKAN_TARGET}) # Compilation to headers need a variable name, the output will be a .h get_filename_component(FILE_NAME ${GLSL_SRC} NAME) set(GLSL_OUT "${COMPILE_DST}/${FILE_NAME}.spv") list(APPEND _SPVS ${GLSL_OUT}) # Appending the output name and the file source list(APPEND COMPILE_CMD -o ${GLSL_OUT} ${GLSL_SRC} ) # The custom command is added to the build system, check for the presence of the output # but also for changes done in GLSL headers add_custom_command( PRE_BUILD OUTPUT ${GLSL_OUT} COMMAND echo ${GLSLC} ${COMPILE_CMD} COMMAND ${GLSLC} ${COMPILE_CMD} MAIN_DEPENDENCY ${GLSL_SRC} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${GLSL_DEPENDENCY} ) endforeach() # Setting OUT variables set(GLSL_SOURCES ${COMPILE_SOURCE_FILES} PARENT_SCOPE) set(GLSL_HEADERS ${COMPILE_HEADER_FILES} PARENT_SCOPE) set(SPV_OUTPUT ${_SPVS} PARENT_SCOPE) endfunction() # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ # ------------------------------------------------------------------------ function(compile_glsl_directory_by_shaderc) set(oneValueArgs SRC DST VULKAN_TARGET DEPENDENCY) set(multiValueArgs FLAGS) cmake_parse_arguments(COMPILE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) # Collecting all source files file(GLOB_RECURSE GLSL_SOURCE_FILES "${COMPILE_SRC}/*.comp" # Compute "${COMPILE_SRC}/*.frag" # Fragment "${COMPILE_SRC}/*.geom" # Geometry "${COMPILE_SRC}/*.mesh" # Mesh "${COMPILE_SRC}/*.rahit" # Ray any hit "${COMPILE_SRC}/*.rcall" # Ray callable "${COMPILE_SRC}/*.rchit" # Ray closest hit "${COMPILE_SRC}/*.rgen" # Ray generation "${COMPILE_SRC}/*.rint" # Ray intersection "${COMPILE_SRC}/*.rmiss" # Ray miss "${COMPILE_SRC}/*.task" # Task "${COMPILE_SRC}/*.tesc" # Tessellation control "${COMPILE_SRC}/*.tese" # Tessellation evaluation "${COMPILE_SRC}/*.vert" # Vertex ) # Collecting headers for dependencies file(GLOB_RECURSE GLSL_HEADER_FILES "${COMPILE_SRC}/*.glsl" # Auto detect - used for header "${COMPILE_SRC}/*.h" ) # By default use Vulkan 1.1 if(NOT DEFINED COMPILE_VULKAN_TARGET) set(COMPILE_VULKAN_TARGET vulkan1.1) endif() # If destination is not present, same as source if(NOT DEFINED COMPILE_DST) set(COMPILE_DST ${COMPILE_SRC}) endif() # If no flag set -g (debug) if(NOT DEFINED COMPILE_FLAGS) set(COMPILE_FLAGS -g) endif() # Compiling all GLSL compile_glsl_by_shaderc(SOURCE_FILES ${GLSL_SOURCE_FILES} HEADER_FILES ${GLSL_HEADER_FILES} DST ${COMPILE_DST} VULKAN_TARGET ${COMPILE_VULKAN_TARGET} DEPENDENCY ${COMPILE_DEPENDENCY} FLAGS ${COMPILE_FLAGS} ) # Setting OUT variables set(GLSL_SOURCES ${GLSL_SOURCE_FILES} PARENT_SCOPE) set(GLSL_HEADERS ${GLSL_HEADER_FILES} PARENT_SCOPE) set(SPV_OUTPUT ${SPV_OUTPUT} PARENT_SCOPE) # propagate value set in compile_glsl endfunction()