diff --git a/CMakeLists.txt b/CMakeLists.txt index ed8922d1..f63d9028 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,3 +53,14 @@ if (BUILD_TESTING) endif() add_subdirectory(src) + +if (CMAKE_CROSSCOMPILING AND IOS_OR_TVOS AND BUILD_SAMPLES) + execute_process( + COMMAND "${CMAKE_COMMAND}" "${CMAKE_CURRENT_SOURCE_DIR}" -BmacOS + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) + execute_process( + COMMAND "${CMAKE_COMMAND}" --build macOS --config Release --target ShaderCompilerCLI -j 16 + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) +endif() diff --git a/cmake/compile_shaders.cmake b/cmake/compile_shaders.cmake new file mode 100644 index 00000000..5c4f6cdb --- /dev/null +++ b/cmake/compile_shaders.cmake @@ -0,0 +1,26 @@ +function(compile_shaders target shaders output) + if (CMAKE_CROSSCOMPILING AND IOS_OR_TVOS) + set(shader_compiler_cli "${CMAKE_BINARY_DIR}/macOS/bin/ShaderCompilerCLI") + else() + set(shader_compiler_cli "$") + endif() + set(output_dir "${CMAKE_BINARY_DIR}/gen/${target}/") + foreach(full_shader_path ${shaders}) + get_filename_component(shader_name ${full_shader_path} NAME_WE) + set(spirv ${output_dir}/${shader_name}.spirv) + set(dxil ${output_dir}/${shader_name}.dxil) + get_property(entrypoint SOURCE ${full_shader_path} PROPERTY SHADER_ENTRYPOINT) + get_property(type SOURCE ${full_shader_path} PROPERTY SHADER_TYPE) + get_property(model SOURCE ${full_shader_path} PROPERTY SHADER_MODEL) + add_custom_command(OUTPUT ${spirv} ${dxil} + COMMAND ${CMAKE_COMMAND} -E echo ${shader_name} ${full_shader_path} ${entrypoint} ${type} ${model} ${output_dir} + COMMAND ${CMAKE_COMMAND} -E make_directory ${output_dir} + COMMAND ${shader_compiler_cli} ${shader_name} ${full_shader_path} ${entrypoint} ${type} ${model} ${output_dir} + DEPENDS ShaderCompilerCLI + MAIN_DEPENDENCY "${full_shader_path}" + ) + set(compiled_shaders ${compiled_shaders} ${spirv}) + set(compiled_shaders ${compiled_shaders} ${dxil}) + endforeach() + set(${output} ${compiled_shaders} PARENT_SCOPE) +endfunction() diff --git a/src/Apps/Triangle/CMakeLists.txt b/src/Apps/Triangle/CMakeLists.txt index 69c59b91..e5e94863 100644 --- a/src/Apps/Triangle/CMakeLists.txt +++ b/src/Apps/Triangle/CMakeLists.txt @@ -2,18 +2,32 @@ list(APPEND sources main.mm ) -list(APPEND resources - PixelShader.spv - VertexShader.spv +set(shaders_path "${assets_path}/shaders/CoreTriangle") + +set(pixel_shaders + ${shaders_path}/PixelShader.hlsl +) +set(vertex_shaders + ${shaders_path}/VertexShader.hlsl ) +set_property(SOURCE ${vertex_shaders} ${pixel_shaders} PROPERTY SHADER_ENTRYPOINT main) +set_property(SOURCE ${vertex_shaders} ${pixel_shaders} PROPERTY SHADER_MODEL 6_0) +set_property(SOURCE ${vertex_shaders} PROPERTY SHADER_TYPE Vertex) +set_property(SOURCE ${pixel_shaders} PROPERTY SHADER_TYPE Pixel) + +set(shaders_files ${pixel_shaders} ${vertex_shaders}) + +include(compile_shaders) +compile_shaders(Triangle "${shaders_files}" resources) + set_source_files_properties(${resources} PROPERTIES MACOSX_PACKAGE_LOCATION Resources ) add_executable(Triangle MACOSX_BUNDLE - ${sources} ${resources} + ${sources} ) target_link_libraries(Triangle diff --git a/src/Apps/Triangle/PixelShader.spv b/src/Apps/Triangle/PixelShader.spv deleted file mode 100644 index c5a42300..00000000 Binary files a/src/Apps/Triangle/PixelShader.spv and /dev/null differ diff --git a/src/Apps/Triangle/VertexShader.spv b/src/Apps/Triangle/VertexShader.spv deleted file mode 100644 index 81dfe45d..00000000 Binary files a/src/Apps/Triangle/VertexShader.spv and /dev/null differ diff --git a/src/Apps/Triangle/main.mm b/src/Apps/Triangle/main.mm index f50c0e8a..23285df7 100644 --- a/src/Apps/Triangle/main.mm +++ b/src/Apps/Triangle/main.mm @@ -82,8 +82,8 @@ constant_buffer->CommitMemory(MemoryType::kUpload); constant_buffer->UpdateUploadBuffer(0, &constant_data, sizeof(constant_data)); - auto vertex_path = [[NSBundle mainBundle] pathForResource:@"VertexShader" ofType:@"spv"]; - auto pixel_path = [[NSBundle mainBundle] pathForResource:@"PixelShader" ofType:@"spv"]; + auto vertex_path = [[NSBundle mainBundle] pathForResource:@"VertexShader" ofType:@"spirv"]; + auto pixel_path = [[NSBundle mainBundle] pathForResource:@"PixelShader" ofType:@"spirv"]; vertex_shader = device->CreateShader(ReadBinaryFile([vertex_path UTF8String]), ShaderBlobType::kSPIRV, ShaderType::kVertex); pixel_shader = diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e70d3509..91b28d1c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,7 @@ if (BUILD_SAMPLES) add_subdirectory(Apps) add_subdirectory(Modules) + add_subdirectory(Tools) endif() add_subdirectory(FlyCube) diff --git a/src/FlyCube/Instance/BaseTypes.h b/src/FlyCube/Instance/BaseTypes.h index 8af0fa2e..fe6fa6ae 100644 --- a/src/FlyCube/Instance/BaseTypes.h +++ b/src/FlyCube/Instance/BaseTypes.h @@ -248,6 +248,8 @@ struct ShaderDesc { std::string model; std::map define; + ShaderDesc() = default; + ShaderDesc(const std::string& shader_path, const std::string& entrypoint, ShaderType type, const std::string& model) : shader_path(shader_path) , entrypoint(entrypoint) diff --git a/src/Tools/CMakeLists.txt b/src/Tools/CMakeLists.txt new file mode 100644 index 00000000..741cb22a --- /dev/null +++ b/src/Tools/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(ShaderCompilerCLI) diff --git a/src/Tools/ShaderCompilerCLI/CMakeLists.txt b/src/Tools/ShaderCompilerCLI/CMakeLists.txt new file mode 100644 index 00000000..6a0622b4 --- /dev/null +++ b/src/Tools/ShaderCompilerCLI/CMakeLists.txt @@ -0,0 +1,24 @@ +if (CMAKE_CROSSCOMPILING) + return() +endif() + +add_executable(ShaderCompilerCLI + ${project_root}/src/FlyCube/HLSLCompiler/Compiler.cpp + ${project_root}/src/FlyCube/HLSLCompiler/DXCLoader.cpp + ${project_root}/src/FlyCube/Utilities/SystemUtils.cpp + main.cpp +) + +target_link_libraries(ShaderCompilerCLI + dxc + gli + glm + nowide +) + +target_include_directories(ShaderCompilerCLI + PUBLIC + "${project_root}/src/FlyCube" +) + +set_target_properties(ShaderCompilerCLI PROPERTIES FOLDER "Tools") diff --git a/src/Tools/ShaderCompilerCLI/main.cpp b/src/Tools/ShaderCompilerCLI/main.cpp new file mode 100644 index 00000000..17b3c6ad --- /dev/null +++ b/src/Tools/ShaderCompilerCLI/main.cpp @@ -0,0 +1,101 @@ +#include "HLSLCompiler/Compiler.h" +#include "Instance/BaseTypes.h" + +#include +#include + +namespace { + +ShaderType GetShaderType(const std::string& target) +{ + if (target == "Pixel") { + return ShaderType::kPixel; + } else if (target == "Vertex") { + return ShaderType::kVertex; + } else if (target == "Compute") { + return ShaderType::kCompute; + } else if (target == "Geometry") { + return ShaderType::kGeometry; + } else if (target == "Amplification") { + return ShaderType::kAmplification; + } else if (target == "Mesh") { + return ShaderType::kMesh; + } else if (target == "Library") { + return ShaderType::kLibrary; + } + assert(false); + return ShaderType::kUnknown; +} + +std::string GetShaderExtension(ShaderBlobType shader_type) +{ + switch (shader_type) { + case ShaderBlobType::kDXIL: + return ".dxil"; + case ShaderBlobType::kSPIRV: + return ".spirv"; + default: + assert(false); + return ".blob"; + } +} + +void CompileShader(const std::string& shader_name, + const ShaderDesc& desc, + const std::string& output_path, + ShaderBlobType shader_type) +{ + std::string path = output_path + "/" + shader_name + GetShaderExtension(shader_type); + std::vector blob = Compile(desc, shader_type); + std::fstream file(path, std::ios::out | std::ios::binary); + file.write(reinterpret_cast(blob.data()), blob.size()); +} + +} // namespace + +class ParseCmd { +public: + ParseCmd(int argc, char* argv[]) + { + size_t arg_index = 0; + auto get_next_arg = [&] { + ++arg_index; + assert(arg_index < argc); + return argv[arg_index]; + }; + m_shader_name = get_next_arg(); + m_desc.shader_path = get_next_arg(); + m_desc.entrypoint = get_next_arg(); + m_desc.type = GetShaderType(get_next_arg()); + m_desc.model = get_next_arg(); + m_output_dir = get_next_arg(); + } + + const std::string& GetShaderName() const + { + return m_shader_name; + } + + const ShaderDesc& GetShaderDesc() const + { + return m_desc; + } + + const std::string& GetOutputDir() const + { + return m_output_dir; + } + +private: + std::string m_shader_name; + ShaderDesc m_desc; + std::string m_output_dir; +}; + +int main(int argc, char* argv[]) +{ + ParseCmd cmd(argc, argv); + CompileShader(cmd.GetShaderName(), cmd.GetShaderDesc(), cmd.GetOutputDir(), ShaderBlobType::kDXIL); + CompileShader(cmd.GetShaderName(), cmd.GetShaderDesc(), cmd.GetOutputDir(), ShaderBlobType::kSPIRV); + return 0; +}