diff --git a/cmake/compile_shaders.cmake b/cmake/compile_shaders.cmake index 5c4f6cdb..8a134400 100644 --- a/cmake/compile_shaders.cmake +++ b/cmake/compile_shaders.cmake @@ -1,12 +1,13 @@ -function(compile_shaders target shaders output) +function(compile_shaders target base_dir output_subdir shaders output_var) 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}/") + set(output_dir "${CMAKE_BINARY_DIR}/bin/${output_subdir}/") foreach(full_shader_path ${shaders}) - get_filename_component(shader_name ${full_shader_path} NAME_WE) + cmake_path(RELATIVE_PATH full_shader_path BASE_DIRECTORY "${base_dir}" OUTPUT_VARIABLE shader_name) + get_filename_component(shader_folder ${shader_name} DIRECTORY) set(spirv ${output_dir}/${shader_name}.spirv) set(dxil ${output_dir}/${shader_name}.dxil) get_property(entrypoint SOURCE ${full_shader_path} PROPERTY SHADER_ENTRYPOINT) @@ -14,13 +15,18 @@ function(compile_shaders target shaders output) 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 ${CMAKE_COMMAND} -E make_directory ${output_dir}/${shader_folder} COMMAND ${shader_compiler_cli} ${shader_name} ${full_shader_path} ${entrypoint} ${type} ${model} ${output_dir} DEPENDS ShaderCompilerCLI MAIN_DEPENDENCY "${full_shader_path}" ) + set_source_files_properties(${spirv} ${dxil} PROPERTIES + MACOSX_PACKAGE_LOCATION "Resources/${output_subdir}/${shader_folder}" + ) + source_group("Shader Files" FILES "${full_shader_path}") + source_group("Shader Blobs" FILES ${spirv} ${dxil}) set(compiled_shaders ${compiled_shaders} ${spirv}) set(compiled_shaders ${compiled_shaders} ${dxil}) endforeach() - set(${output} ${compiled_shaders} PARENT_SCOPE) + set(${output_var} ${compiled_shaders} PARENT_SCOPE) endfunction() diff --git a/src/Apps/CMakeLists.txt b/src/Apps/CMakeLists.txt index 37319301..775d8080 100644 --- a/src/Apps/CMakeLists.txt +++ b/src/Apps/CMakeLists.txt @@ -6,6 +6,4 @@ if (NOT IOS_OR_TVOS) add_subdirectory(CoreTriangle) endif() -if (APPLE) - add_subdirectory(Triangle) -endif() +add_subdirectory(Triangle) diff --git a/src/Apps/Triangle/CMakeLists.txt b/src/Apps/Triangle/CMakeLists.txt index e5e94863..586308ff 100644 --- a/src/Apps/Triangle/CMakeLists.txt +++ b/src/Apps/Triangle/CMakeLists.txt @@ -1,5 +1,5 @@ list(APPEND sources - main.mm + main.cpp ) set(shaders_path "${assets_path}/shaders/CoreTriangle") @@ -19,17 +19,20 @@ 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) +compile_shaders(Triangle "${shaders_path}" "asserts/Triangle" "${shaders_files}" resources) -set_source_files_properties(${resources} PROPERTIES - MACOSX_PACKAGE_LOCATION Resources -) - -add_executable(Triangle MACOSX_BUNDLE +add_executable(Triangle WIN32 MACOSX_BUNDLE ${resources} + ${shaders_files} ${sources} ) +if (WIN32) + set_target_properties(CoreTriangle PROPERTIES + LINK_FLAGS "/ENTRY:mainCRTStartup" + ) +endif() + target_link_libraries(Triangle AppLoop AppSettings diff --git a/src/Apps/Triangle/main.mm b/src/Apps/Triangle/main.cpp similarity index 91% rename from src/Apps/Triangle/main.mm rename to src/Apps/Triangle/main.cpp index 23285df7..1ca9b4e6 100644 --- a/src/Apps/Triangle/main.mm +++ b/src/Apps/Triangle/main.cpp @@ -4,8 +4,6 @@ #include "Instance/Instance.h" #include "Utilities/Common.h" -#import - class TriangleRenderer : public AppRenderer { public: TriangleRenderer(const Settings& settings); @@ -82,12 +80,17 @@ constant_buffer->CommitMemory(MemoryType::kUpload); constant_buffer->UpdateUploadBuffer(0, &constant_data, sizeof(constant_data)); - 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 = - device->CreateShader(ReadBinaryFile([pixel_path UTF8String]), ShaderBlobType::kSPIRV, ShaderType::kPixel); + ShaderBlobType blob_type = device->GetSupportedShaderBlobType(); + std::string shader_blob_ext; + if (blob_type == ShaderBlobType::kDXIL) { + shader_blob_ext = ".dxil"; + } else { + shader_blob_ext = ".spirv"; + } + std::string vertex_path = GetAssertPath("asserts/Triangle/VertexShader.hlsl" + shader_blob_ext); + std::string pixel_path = GetAssertPath("asserts/Triangle/PixelShader.hlsl" + shader_blob_ext); + vertex_shader = device->CreateShader(ReadBinaryFile(vertex_path), ShaderBlobType::kSPIRV, ShaderType::kVertex); + pixel_shader = device->CreateShader(ReadBinaryFile(pixel_path), ShaderBlobType::kSPIRV, ShaderType::kPixel); program = device->CreateProgram({ vertex_shader, pixel_shader }); ViewDesc constant_view_desc = {}; diff --git a/src/FlyCube/CMakeLists.txt b/src/FlyCube/CMakeLists.txt index bf35ed0d..089eb9a1 100644 --- a/src/FlyCube/CMakeLists.txt +++ b/src/FlyCube/CMakeLists.txt @@ -239,6 +239,7 @@ if (APPLE AND VULKAN_SUPPORT) endif() list(APPEND Utilities + Utilities/Common.cpp Utilities/Common.h Utilities/DXGIFormatHelper.cpp Utilities/DXGIFormatHelper.h @@ -251,6 +252,10 @@ list(APPEND Utilities Utilities/VKUtility.h ) +if (APPLE AND VULKAN_SUPPORT) + set_property(SOURCE Utilities/Common.cpp PROPERTY COMPILE_FLAGS "-xobjective-c++") +endif() + list(APPEND View $<$:View/DXView.cpp> $<$:View/DXView.h> @@ -293,6 +298,7 @@ if (UNIX AND NOT APPLE) endif() target_link_libraries(FlyCube + $<$:-framework\ Foundation> $<$:-framework\ QuartzCore> $<$:d3d12> $<$:dxgi> diff --git a/src/FlyCube/Device/DXDevice.cpp b/src/FlyCube/Device/DXDevice.cpp index 83723e09..6c5c58a3 100644 --- a/src/FlyCube/Device/DXDevice.cpp +++ b/src/FlyCube/Device/DXDevice.cpp @@ -572,6 +572,11 @@ RaytracingASPrebuildInfo DXDevice::GetTLASPrebuildInfo(uint32_t instance_count, return GetAccelerationStructurePrebuildInfo(inputs); } +ShaderBlobType DXDevice::GetSupportedShaderBlobType() const +{ + return ShaderBlobType::kDXIL; +} + DXAdapter& DXDevice::GetAdapter() { return m_adapter; diff --git a/src/FlyCube/Device/DXDevice.h b/src/FlyCube/Device/DXDevice.h index 028ba687..94174333 100644 --- a/src/FlyCube/Device/DXDevice.h +++ b/src/FlyCube/Device/DXDevice.h @@ -73,6 +73,7 @@ class DXDevice : public Device { BuildAccelerationStructureFlags flags) const override; RaytracingASPrebuildInfo GetTLASPrebuildInfo(uint32_t instance_count, BuildAccelerationStructureFlags flags) const override; + ShaderBlobType GetSupportedShaderBlobType() const override; DXAdapter& GetAdapter(); ComPtr GetDevice(); diff --git a/src/FlyCube/Device/Device.h b/src/FlyCube/Device/Device.h index d6ac56d4..1463546d 100644 --- a/src/FlyCube/Device/Device.h +++ b/src/FlyCube/Device/Device.h @@ -81,4 +81,5 @@ class Device : public QueryInterface { BuildAccelerationStructureFlags flags) const = 0; virtual RaytracingASPrebuildInfo GetTLASPrebuildInfo(uint32_t instance_count, BuildAccelerationStructureFlags flags) const = 0; + virtual ShaderBlobType GetSupportedShaderBlobType() const = 0; }; diff --git a/src/FlyCube/Device/MTDevice.h b/src/FlyCube/Device/MTDevice.h index 55475a55..bed696fe 100644 --- a/src/FlyCube/Device/MTDevice.h +++ b/src/FlyCube/Device/MTDevice.h @@ -89,6 +89,7 @@ class MTDevice : public Device, protected MVKPhysicalDeviceImpl { BuildAccelerationStructureFlags flags) const override; RaytracingASPrebuildInfo GetTLASPrebuildInfo(uint32_t instance_count, BuildAccelerationStructureFlags flags) const override; + ShaderBlobType GetSupportedShaderBlobType() const override; const id& GetDevice() const; MVKPixelFormats& GetMVKPixelFormats(); diff --git a/src/FlyCube/Device/MTDevice.mm b/src/FlyCube/Device/MTDevice.mm index 72dbe539..6a7496f4 100644 --- a/src/FlyCube/Device/MTDevice.mm +++ b/src/FlyCube/Device/MTDevice.mm @@ -350,6 +350,11 @@ return prebuild_info; } +ShaderBlobType MTDevice::GetSupportedShaderBlobType() const +{ + return ShaderBlobType::kSPIRV; +} + const id& MTDevice::GetDevice() const { return m_device; diff --git a/src/FlyCube/Device/VKDevice.cpp b/src/FlyCube/Device/VKDevice.cpp index ec69e587..b6e81950 100644 --- a/src/FlyCube/Device/VKDevice.cpp +++ b/src/FlyCube/Device/VKDevice.cpp @@ -774,6 +774,11 @@ RaytracingASPrebuildInfo VKDevice::GetTLASPrebuildInfo(uint32_t instance_count, return GetAccelerationStructurePrebuildInfo(acceleration_structure_info, { instance_count }); } +ShaderBlobType VKDevice::GetSupportedShaderBlobType() const +{ + return ShaderBlobType::kSPIRV; +} + VKAdapter& VKDevice::GetAdapter() { return m_adapter; diff --git a/src/FlyCube/Device/VKDevice.h b/src/FlyCube/Device/VKDevice.h index 286a2ca8..a6acb761 100644 --- a/src/FlyCube/Device/VKDevice.h +++ b/src/FlyCube/Device/VKDevice.h @@ -66,6 +66,7 @@ class VKDevice : public Device { BuildAccelerationStructureFlags flags) const override; RaytracingASPrebuildInfo GetTLASPrebuildInfo(uint32_t instance_count, BuildAccelerationStructureFlags flags) const override; + ShaderBlobType GetSupportedShaderBlobType() const override; VKAdapter& GetAdapter(); vk::Device GetDevice(); diff --git a/src/FlyCube/Utilities/Common.cpp b/src/FlyCube/Utilities/Common.cpp new file mode 100644 index 00000000..3dca5517 --- /dev/null +++ b/src/FlyCube/Utilities/Common.cpp @@ -0,0 +1,46 @@ +#include "Utilities/Common.h" + +#include "Utilities/SystemUtils.h" + +#include +#include +#include + +#if defined(__APPLE__) +#import +#endif + +uint64_t Align(uint64_t size, uint64_t alignment) +{ + return (size + (alignment - 1)) & ~(alignment - 1); +} + +std::vector ReadBinaryFile(const std::string& filepath) +{ + std::ifstream file(filepath, std::ios::binary); + file.unsetf(std::ios::skipws); + + std::streampos filesize; + file.seekg(0, std::ios::end); + filesize = file.tellg(); + file.seekg(0, std::ios::beg); + + std::vector data; + data.reserve(filesize); + data.insert(data.begin(), std::istream_iterator(file), std::istream_iterator()); + return data; +} + +std::string GetAssertPath(const std::string& filepath) +{ +#if defined(__APPLE__) + auto path = std::filesystem::path(filepath); + auto resource = [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:path.stem().c_str()] + ofType:[NSString stringWithUTF8String:path.extension().c_str()] + inDirectory:[NSString stringWithUTF8String:path.parent_path().c_str()]]; + if (resource) { + return [resource UTF8String]; + } +#endif + return GetExecutableDir() + "\\" + filepath; +} diff --git a/src/FlyCube/Utilities/Common.h b/src/FlyCube/Utilities/Common.h index ec3cbb08..b42d8298 100644 --- a/src/FlyCube/Utilities/Common.h +++ b/src/FlyCube/Utilities/Common.h @@ -1,26 +1,9 @@ #pragma once + #include -#include -#include +#include #include -inline uint64_t Align(uint64_t size, uint64_t alignment) -{ - return (size + (alignment - 1)) & ~(alignment - 1); -} - -inline std::vector ReadBinaryFile(const std::string& filename) -{ - std::ifstream file(filename, std::ios::binary); - file.unsetf(std::ios::skipws); - - std::streampos filesize; - file.seekg(0, std::ios::end); - filesize = file.tellg(); - file.seekg(0, std::ios::beg); - - std::vector data; - data.reserve(filesize); - data.insert(data.begin(), std::istream_iterator(file), std::istream_iterator()); - return data; -} +uint64_t Align(uint64_t size, uint64_t alignment); +std::vector ReadBinaryFile(const std::string& filepath); +std::string GetAssertPath(const std::string& filepath); diff --git a/src/FlyCube/Utilities/FormatHelper.cpp b/src/FlyCube/Utilities/FormatHelper.cpp index 28c5b40c..06d392dd 100644 --- a/src/FlyCube/Utilities/FormatHelper.cpp +++ b/src/FlyCube/Utilities/FormatHelper.cpp @@ -1,9 +1,6 @@ #include "Utilities/FormatHelper.h" -inline uint32_t Align(uint32_t size, uint32_t alignment) -{ - return (size + (alignment - 1)) & ~(alignment - 1); -} +#include "Utilities/Common.h" void GetFormatInfo(size_t width, size_t height,