71 lines
2.3 KiB
CMake
71 lines
2.3 KiB
CMake
# compile_shaders.cmake — invoked via `cmake -P`.
|
|
#
|
|
# Required cache vars:
|
|
# GLSLC — path to the glslc executable.
|
|
# SHADERS_DIR — path to the shaders/ directory.
|
|
#
|
|
# Walks SHADERS_DIR for:
|
|
# _common/passthrough.vk.glsl -> _common/passthrough.vert.spv
|
|
# <name>/<name>.vk.glsl -> <name>/<name>.frag.spv
|
|
#
|
|
# Shaders are recompiled only if the .spv is missing or older than its source.
|
|
|
|
if(NOT GLSLC)
|
|
message(FATAL_ERROR "compile_shaders.cmake: GLSLC not provided")
|
|
endif()
|
|
if(NOT SHADERS_DIR)
|
|
message(FATAL_ERROR "compile_shaders.cmake: SHADERS_DIR not provided")
|
|
endif()
|
|
if(NOT EXISTS "${SHADERS_DIR}")
|
|
message(FATAL_ERROR "compile_shaders.cmake: SHADERS_DIR does not exist: ${SHADERS_DIR}")
|
|
endif()
|
|
|
|
function(_compile_to_spv SOURCE STAGE OUTPUT)
|
|
if(EXISTS "${OUTPUT}")
|
|
file(TIMESTAMP "${SOURCE}" SRC_T "%s")
|
|
file(TIMESTAMP "${OUTPUT}" OUT_T "%s")
|
|
if(NOT "${SRC_T}" STREQUAL "" AND NOT "${OUT_T}" STREQUAL "")
|
|
if(SRC_T LESS_EQUAL OUT_T)
|
|
return()
|
|
endif()
|
|
endif()
|
|
endif()
|
|
message(STATUS "glslc (${STAGE}) ${SOURCE} -> ${OUTPUT}")
|
|
execute_process(
|
|
COMMAND "${GLSLC}" "-fshader-stage=${STAGE}" "${SOURCE}" -o "${OUTPUT}"
|
|
RESULT_VARIABLE RC
|
|
OUTPUT_VARIABLE STDOUT
|
|
ERROR_VARIABLE STDERR
|
|
)
|
|
if(NOT RC EQUAL 0)
|
|
message(FATAL_ERROR "glslc failed for ${SOURCE}:\n${STDERR}")
|
|
endif()
|
|
endfunction()
|
|
|
|
set(VERT_SOURCE "${SHADERS_DIR}/_common/passthrough.vk.glsl")
|
|
set(VERT_OUTPUT "${SHADERS_DIR}/_common/passthrough.vert.spv")
|
|
if(EXISTS "${VERT_SOURCE}")
|
|
_compile_to_spv("${VERT_SOURCE}" "vert" "${VERT_OUTPUT}")
|
|
else()
|
|
message(WARNING "Missing shared vertex shader: ${VERT_SOURCE}")
|
|
endif()
|
|
|
|
file(GLOB SHADER_DIRS LIST_DIRECTORIES true RELATIVE "${SHADERS_DIR}" "${SHADERS_DIR}/*")
|
|
foreach(DIR ${SHADER_DIRS})
|
|
set(ABS_DIR "${SHADERS_DIR}/${DIR}")
|
|
if(NOT IS_DIRECTORY "${ABS_DIR}")
|
|
continue()
|
|
endif()
|
|
string(SUBSTRING "${DIR}" 0 1 FIRST_CHAR)
|
|
if(FIRST_CHAR STREQUAL "_" OR FIRST_CHAR STREQUAL ".")
|
|
continue()
|
|
endif()
|
|
|
|
set(VK_SOURCE "${ABS_DIR}/${DIR}.vk.glsl")
|
|
set(SPV_OUTPUT "${ABS_DIR}/${DIR}.frag.spv")
|
|
|
|
if(EXISTS "${VK_SOURCE}")
|
|
_compile_to_spv("${VK_SOURCE}" "frag" "${SPV_OUTPUT}")
|
|
endif()
|
|
endforeach()
|