diff --git a/CMakeLists.txt b/CMakeLists.txt index c7631d4..87e9e51 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,9 @@ include(${CMAKE_CURRENT_LIST_DIR}/cmake/Common.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cmake/AddPlatformExecutable.cmake) include(FetchContent) +#set(SHADER_COMPILER_COMMAND $) +# set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool") + if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") message("Linux build detected!") @@ -17,6 +20,9 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(ENABLE_VULKAN TRUE) set(ENABLE_LINUX TRUE) + + set(NEEDS_HOSTED_SHADER_COMPILER FALSE) + set(REQUIRED_SHADER_LANGUAGE "spirv") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" AND NOT IOS) @@ -30,6 +36,8 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" AND NOT IOS) set(ENABLE_METAL TRUE) set(CMAKE_XCODE_GENERATE_SCHEME OFF) + set(NEEDS_HOSTED_SHADER_COMPILER FALSE) + set(REQUIRED_SHADER_LANGUAGE "msl") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS") @@ -39,6 +47,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "iOS") set(ENABLE_DARWIN TRUE) set(ENABLE_IOS TRUE) set(ENABLE_METAL TRUE) + + set(NEEDS_HOSTED_SHADER_COMPILER TRUE) + set(REQUIRED_SHADER_LANGUAGE "msl") + set(EXTRA_PLATFORM_ARG "mobile") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS") @@ -48,6 +60,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "tvOS") set(ENABLE_DARWIN TRUE) set(ENABLE_TVOS TRUE) set(ENABLE_METAL TRUE) + + set(NEEDS_HOSTED_SHADER_COMPILER TRUE) + set(REQUIRED_SHADER_LANGUAGE "msl") + set(EXTRA_PLATFORM_ARG "mobile") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") @@ -57,12 +73,16 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") set(ENABLE_WINDOWS TRUE) set(ENABLE_VULKAN TRUE) + + set(NEEDS_HOSTED_SHADER_COMPILER FALSE) + set(REQUIRED_SHADER_LANGUAGE "spirv") endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "WindowsStore") message("UWP build detected!") set(ENABLE_UWP TRUE) + set(NEEDS_HOSTED_SHADER_COMPILER TRUE) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") @@ -72,6 +92,13 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten") set(ENABLE_WEB TRUE) set(ENABLE_WEBGPU TRUE) + + set(NEEDS_HOSTED_SHADER_COMPILER TRUE) + set(REQUIRED_SHADER_LANGUAGE "wgsl") +endif() + +if(NEEDS_HOSTED_SHADER_COMPILER AND (NOT DEFINED SHADER_COMPILER_LOCATION)) + message(FATAL_ERROR "You are building for a platform that needs a hosted shader compiler. Please specify the path in SHADER_COMPILER_LOCATION!") endif() set(CROSS_LIBS diff --git a/cmake/BuildShaders.cmake b/cmake/BuildShaders.cmake index a243329..1288778 100755 --- a/cmake/BuildShaders.cmake +++ b/cmake/BuildShaders.cmake @@ -4,18 +4,15 @@ function(add_shader_command) cmake_path(REMOVE_EXTENSION ARGS_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT) - set(SHADER_COMPILER_COMMAND $) - set(EXTRA_PLATFORM_ARG "0") - - # if targeting ios, we want to use the host's shader compiler - if(ENABLE_IOS OR ENABLE_TVOS) - set(SHADER_COMPILER_COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/../build/bin/Debug/ShaderCompilerTool") - set(EXTRA_PLATFORM_ARG "1") - endif() - set(SRC_FILENAME ${CMAKE_CURRENT_SOURCE_DIR}/${ARGS_FILENAME}) set(OUTPUT_FILENAME ${CMAKE_BINARY_DIR}/${FILENAME_WITHOUT_EXT}) + if(NEEDS_HOSTED_SHADER_COMPILER) + set(SHADER_COMPILER_COMMAND ${SHADER_COMPILER_LOCATION}) + else() + set(SHADER_COMPILER_COMMAND $) + endif() + # we want to remove the .nocompile extension just like the tool does, if it exists cmake_path(GET FILENAME_WITHOUT_EXT EXTENSION LAST_ONLY LAST_EXT) @@ -25,7 +22,7 @@ function(add_shader_command) add_custom_command( OUTPUT ${OUTPUT_FILENAME} - COMMAND ${SHADER_COMPILER_COMMAND} ${SRC_FILENAME} ${OUTPUT_FILENAME} ${EXTRA_PLATFORM_ARG} + COMMAND ${SHADER_COMPILER_COMMAND} ${SRC_FILENAME} ${OUTPUT_FILENAME} ${REQUIRED_SHADER_LANGUAGE} ${EXTRA_PLATFORM_ARG} DEPENDS ${SRC_FILENAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/shaders) @@ -35,21 +32,24 @@ endfunction() # add shaders to target function(add_shaders) - if(NOT ENABLE_IOS AND NOT ENABLE_TVOS AND NOT ENABLE_WEB) - cmake_parse_arguments(ARGS "" "TARGET" "SHADERS" ${ARGN}) + cmake_parse_arguments(ARGS "" "TARGET" "SHADERS" ${ARGN}) - foreach(SHADER_FILENAME ${ARGS_SHADERS}) - cmake_path(REMOVE_EXTENSION SHADER_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT) + foreach(SHADER_FILENAME ${ARGS_SHADERS}) + cmake_path(REMOVE_EXTENSION SHADER_FILENAME LAST_ONLY OUTPUT_VARIABLE FILENAME_WITHOUT_EXT) - add_shader_command(FILENAME ${SHADER_FILENAME} OUT DST_FILENAME) + add_shader_command(FILENAME ${SHADER_FILENAME} OUT DST_FILENAME) - list(APPEND SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_FILENAME}) - list(APPEND DST_FILES ${DST_FILENAME}) - endforeach() + list(APPEND SRC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${SHADER_FILENAME}) + list(APPEND DST_FILES ${DST_FILENAME}) + endforeach() + if(NOT NEEDS_HOSTED_SHADER_COMPILER) add_custom_target(BuildShaders DEPENDS ShaderCompilerTool ${DST_FILES}) - add_dependencies(${ARGS_TARGET} BuildShaders) + else() + add_custom_target(BuildShaders DEPENDS ${DST_FILES}) endif() + + add_dependencies(${ARGS_TARGET} BuildShaders) endfunction() # make the shader directory if it doesnt exist already diff --git a/tools/shadercompiler/main.cpp b/tools/shadercompiler/main.cpp index dada7a8..bfe784b 100755 --- a/tools/shadercompiler/main.cpp +++ b/tools/shadercompiler/main.cpp @@ -4,6 +4,7 @@ #include "shadercompiler.hpp" #include "log.hpp" #include "string_utils.hpp" +#include "utility.hpp" bool has_extension(const std::filesystem::path& path, const std::string_view extension) { return string_contains(path.filename().string(), extension); @@ -16,10 +17,28 @@ int main(int argc, char* argv[]) { } shader_compiler.set_include_path(std::filesystem::current_path().string()); - + std::filesystem::path source_path = argv[1]; std::filesystem::path destination_path = argv[2]; + ShaderLanguage language = ShaderLanguage::SPIRV; + std::string_view shader_language_string = argv[3]; + if(shader_language_string == "spirv") { + language = ShaderLanguage::SPIRV; + } else if(shader_language_string == "msl") { + language = ShaderLanguage::MSL; + } else if(shader_language_string == "wgsl") { + language = ShaderLanguage::WGSL; + } else if(shader_language_string == "glsl") { + language = ShaderLanguage::GLSL; + } + + CompileOptions options; + + std::string_view extra_options = argc > 4 ? argv[4] : ""; + if(extra_options == "mobile") + options.is_apple_mobile = true; + std::ifstream t(source_path); std::stringstream buffer; buffer << t.rdbuf(); @@ -38,16 +57,6 @@ int main(int argc, char* argv[]) { else if(has_extension(source_path, ".comp")) stage = ShaderStage::Compute; - ShaderLanguage language; - CompileOptions options; -#ifdef PLATFORM_MACOS - options.is_apple_mobile = (bool)argv[3]; - - language = ShaderLanguage::MSL; -#else - language = ShaderLanguage::SPIRV; -#endif - const auto compiled_source = shader_compiler.compile(ShaderLanguage::GLSL, stage, ShaderSource(buffer.str()), language, options); if(!compiled_source.has_value()) { prism::log("Error when compiling {}!", source_path.string()); @@ -55,6 +64,8 @@ int main(int argc, char* argv[]) { } switch(language) { + // right now, WGSL is outputted as SPIR-V with some WGSL compatibility stuff included + case ShaderLanguage::WGSL: case ShaderLanguage::SPIRV: { const auto spirv = compiled_source->as_bytecode();