76 lines
3.3 KiB
CMake
76 lines
3.3 KiB
CMake
if(NOT DEFINED PP_SHADER_DIR)
|
|
message(FATAL_ERROR "PP_SHADER_DIR is required")
|
|
endif()
|
|
|
|
file(REAL_PATH "${PP_SHADER_DIR}" pp_shader_dir)
|
|
if(NOT IS_DIRECTORY "${pp_shader_dir}")
|
|
message(FATAL_ERROR "Shader directory does not exist: ${pp_shader_dir}")
|
|
endif()
|
|
|
|
file(GLOB_RECURSE pp_shader_files
|
|
"${pp_shader_dir}/*.glsl")
|
|
|
|
if(NOT pp_shader_files)
|
|
message(FATAL_ERROR "No shader files found under: ${pp_shader_dir}")
|
|
endif()
|
|
|
|
set(pp_shader_errors "")
|
|
set(pp_top_level_count 0)
|
|
set(pp_include_count 0)
|
|
|
|
foreach(pp_shader_file IN LISTS pp_shader_files)
|
|
file(RELATIVE_PATH pp_shader_rel "${pp_shader_dir}" "${pp_shader_file}")
|
|
file(READ "${pp_shader_file}" pp_shader_contents)
|
|
|
|
string(REGEX MATCHALL "#[ \t]*include[ \t]+\"[^\"]+\"" pp_include_lines "${pp_shader_contents}")
|
|
foreach(pp_include_line IN LISTS pp_include_lines)
|
|
string(REGEX REPLACE ".*\"([^\"]+)\".*" "\\1" pp_include_path "${pp_include_line}")
|
|
if(pp_include_path MATCHES "^/")
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: include path must be relative: ${pp_include_path}")
|
|
endif()
|
|
if(pp_include_path MATCHES "^[A-Za-z]:")
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: include path must not be drive-absolute: ${pp_include_path}")
|
|
endif()
|
|
if(pp_include_path MATCHES "\\.\\.")
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: include path must not traverse parent directories: ${pp_include_path}")
|
|
endif()
|
|
if(NOT EXISTS "${pp_shader_dir}/${pp_include_path}")
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: missing include: ${pp_include_path}")
|
|
endif()
|
|
endforeach()
|
|
|
|
if(pp_shader_rel MATCHES "^include/")
|
|
math(EXPR pp_include_count "${pp_include_count} + 1")
|
|
if(pp_shader_contents MATCHES "\\[\\[(vertex|fragment)\\]\\]")
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: include shaders must not declare stage markers")
|
|
endif()
|
|
else()
|
|
math(EXPR pp_top_level_count "${pp_top_level_count} + 1")
|
|
|
|
string(REGEX MATCHALL "\\[\\[vertex\\]\\]" pp_vertex_markers "${pp_shader_contents}")
|
|
string(REGEX MATCHALL "\\[\\[fragment\\]\\]" pp_fragment_markers "${pp_shader_contents}")
|
|
list(LENGTH pp_vertex_markers pp_vertex_count)
|
|
list(LENGTH pp_fragment_markers pp_fragment_count)
|
|
|
|
if(NOT pp_vertex_count EQUAL 1)
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: expected exactly one [[vertex]] marker")
|
|
endif()
|
|
if(NOT pp_fragment_count EQUAL 1)
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: expected exactly one [[fragment]] marker")
|
|
endif()
|
|
|
|
string(FIND "${pp_shader_contents}" "[[vertex]]" pp_vertex_pos)
|
|
string(FIND "${pp_shader_contents}" "[[fragment]]" pp_fragment_pos)
|
|
if(pp_vertex_pos GREATER_EQUAL 0 AND pp_fragment_pos GREATER_EQUAL 0 AND NOT pp_vertex_pos LESS pp_fragment_pos)
|
|
list(APPEND pp_shader_errors "${pp_shader_rel}: [[vertex]] marker must appear before [[fragment]]")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
if(pp_shader_errors)
|
|
list(JOIN pp_shader_errors "\n" pp_shader_error_text)
|
|
message(FATAL_ERROR "Shader validation failed:\n${pp_shader_error_text}")
|
|
endif()
|
|
|
|
message(STATUS "Validated ${pp_top_level_count} shader programs and ${pp_include_count} shader includes under ${pp_shader_dir}")
|