From dbd7b2dad54a4506070b86b76d4f79cab378a9f1 Mon Sep 17 00:00:00 2001 From: Metehan Tuncbilek Date: Tue, 16 Jul 2024 18:31:43 +0300 Subject: [PATCH] review refactors --- cmake/SetupVulkan.cmake | 15 ++--- openVulkanoCpp/Base/Utils.cpp | 13 +--- openVulkanoCpp/Shader/ShaderCompiler.cpp | 75 ++++++++++++++++++++---- openVulkanoCpp/Shader/ShaderCompiler.hpp | 36 +++--------- openVulkanoCpp/Shader/test.vert | 8 --- openVulkanoCpp/Shader/test1.glsl | 3 - 6 files changed, 79 insertions(+), 71 deletions(-) delete mode 100644 openVulkanoCpp/Shader/test.vert delete mode 100644 openVulkanoCpp/Shader/test1.glsl diff --git a/cmake/SetupVulkan.cmake b/cmake/SetupVulkan.cmake index b386f3a..24ed595 100644 --- a/cmake/SetupVulkan.cmake +++ b/cmake/SetupVulkan.cmake @@ -4,17 +4,12 @@ function(SetupVulkan TARGET) target_link_libraries(${TARGET} PRIVATE ${MoltenVK_LIBRARIES}) else () find_package(Vulkan REQUIRED) - get_filename_component(Vulkan_SDK_DIR "${Vulkan_LIBRARIES}" DIRECTORY) # Get VulkanSDK/[version]/Bin target_link_libraries(${TARGET} PRIVATE Vulkan::Vulkan) - if(CMAKE_BUILD_TYPE MATCHES "Debug") - target_link_libraries(${TARGET} PRIVATE "${Vulkan_SDK_DIR}/shaderc_combinedd.lib" - "${Vulkan_SDK_DIR}/spirv-cross-cored.lib" "${Vulkan_SDK_DIR}/spirv-cross-glsld.lib" - "${Vulkan_SDK_DIR}/spirv-cross-hlsld.lib") - else() - target_link_libraries(${TARGET} PRIVATE "${Vulkan_SDK_DIR}/shaderc_combined.lib" - "${Vulkan_SDK_DIR}/spirv-cross-core.lib" "${Vulkan_SDK_DIR}/spirv-cross-glsl.lib" - "${Vulkan_SDK_DIR}/spirv-cross-hlsl.lib") - endif() + find_package(Vulkan OPTIONAL_COMPONENTS shaderc_combined) + if (Vulkan_shaderc_combined_FOUND) + target_link_libraries(${TARGET} PRIVATE Vulkan::shaderc_combined) + target_compile_definitions(${TARGET} PRIVATE HAS_SHADERC) + endif () endif () target_include_directories(${TARGET} PUBLIC ${Vulkan_INCLUDE_DIR}) diff --git a/openVulkanoCpp/Base/Utils.cpp b/openVulkanoCpp/Base/Utils.cpp index cbdd6ed..4987888 100644 --- a/openVulkanoCpp/Base/Utils.cpp +++ b/openVulkanoCpp/Base/Utils.cpp @@ -70,19 +70,10 @@ namespace OpenVulkano throw std::runtime_error("Failed to open file '" + filePath + "'!"); } const size_t fileSize = static_cast(file.tellg()); - if (nullTerminateString) - { - Array data(fileSize + 1); - file.seekg(0); - file.read(data.Data(), fileSize); - data[fileSize] = '\0'; - file.close(); - return data; - } - - Array data(fileSize); + Array data(fileSize + nullTerminateString); file.seekg(0); file.read(data.Data(), fileSize); + if (nullTerminateString) data[fileSize] = '\0'; file.close(); return data; } diff --git a/openVulkanoCpp/Shader/ShaderCompiler.cpp b/openVulkanoCpp/Shader/ShaderCompiler.cpp index 548986d..e8ccec7 100644 --- a/openVulkanoCpp/Shader/ShaderCompiler.cpp +++ b/openVulkanoCpp/Shader/ShaderCompiler.cpp @@ -2,41 +2,93 @@ #include "Base/Logger.hpp" +#include #include namespace OpenVulkano { - Unique ShaderCompiler::CompileGLSLToSpirv(const std::string& absPath, const std::string& incPath, - const std::string& entryPoint, shaderc_shader_kind shaderStage, - bool bHaveIncludes) +#if defined(HAS_SHADERC) + class ShaderIncluder : public shaderc::CompileOptions::IncluderInterface + { + struct IncludeData + { + shaderc_include_result result = {}; + std::string m_fullPath; + Array m_content; + }; + + public: + ShaderIncluder(const std::string& path); + ~ShaderIncluder() override = default; + + shaderc_include_result* GetInclude(const char* requestedSource, shaderc_include_type type, + const char* requestingSource, uint64_t includeDepth) override; + void ReleaseInclude(shaderc_include_result* data) override; + + private: + std::string ResolveInclude(const std::string& requestedSource) const; + + private: + std::string m_includePath; + }; + + shaderc_shader_kind CheckStage(const std::string& extensionName) + { + std::map stageMap = { + { "vert", shaderc_glsl_vertex_shader }, { "frag", shaderc_glsl_fragment_shader }, + { "comp", shaderc_glsl_compute_shader }, { "geom", shaderc_glsl_geometry_shader }, + { "tesc", shaderc_glsl_tess_control_shader }, { "tese", shaderc_glsl_tess_evaluation_shader }, + { "rgen", shaderc_glsl_raygen_shader }, { "rint", shaderc_glsl_intersection_shader }, + { "rahit", shaderc_glsl_anyhit_shader }, { "rchit", shaderc_glsl_closesthit_shader }, + { "rmiss", shaderc_glsl_miss_shader }, { "rcall", shaderc_glsl_callable_shader }, + { "task", shaderc_glsl_task_shader }, { "mesh", shaderc_glsl_mesh_shader } + }; + + auto it = stageMap.find(extensionName); + if (it != stageMap.end()) return it->second; + else throw std::runtime_error("Failed to find shader stage for extension '" + extensionName + "'!"); + } + + Array ShaderCompiler::CompileGLSLToSpirv(const std::string& absPath, bool hasIncludes, + const std::string& incPath, const std::string& entryPoint) { Array file = Utils::ReadFile(absPath, false, true); shaderc::Compiler shaderCompiler; shaderc::CompileOptions options; - if (bHaveIncludes) options.SetIncluder(std::make_unique(incPath)); + if (hasIncludes && incPath.size() > 0) { options.SetIncluder(std::make_unique(incPath)); } options.SetSourceLanguage(shaderc_source_language_glsl); options.SetSuppressWarnings(); + auto extensionSplit = Utils::SplitAtLastOccurrence(absPath, '.'); + shaderc::PreprocessedSourceCompilationResult preResult = - shaderCompiler.PreprocessGlsl(file.Data(), shaderStage, entryPoint.c_str(), options); + shaderCompiler.PreprocessGlsl(file.Data(), CheckStage(extensionSplit.second), entryPoint.c_str(), options); + + #if defined(_DEBUG) + std::string test = static_cast(preResult.begin(), preResult.end()); + // printf("Preprocessed shader: %s\n\n\n", test.c_str()); // Works fine + // Logger::APP->info("Preprocessed shader: {0}", test); gives error + #endif if (preResult.GetCompilationStatus() != shaderc_compilation_status_success) { throw std::runtime_error("Failed preprocessing shader. Reason: " + preResult.GetErrorMessage()); } - shaderc::CompilationResult result = - shaderCompiler.CompileGlslToSpv(static_cast(preResult.begin()), shaderStage, "", options); + shaderc::CompilationResult result = shaderCompiler.CompileGlslToSpv( + static_cast(preResult.begin()), CheckStage(extensionSplit.second), "", options); if (result.GetCompilationStatus() != shaderc_compilation_status_success) { throw std::runtime_error("Failed compiling shader. Reason: " + result.GetErrorMessage()); } - Unique spirv = std::make_unique((void*) result.begin()); - return spirv; + Array returnResult(result.cend() - result.cbegin()); + // Copy the data to the return array + std::copy(result.begin(), result.end(), returnResult.Data()); + return returnResult; } ShaderIncluder::ShaderIncluder(const std::string& path) : m_includePath(path) {} @@ -46,7 +98,9 @@ namespace OpenVulkano { IncludeData* includeData = new IncludeData(); includeData->m_fullPath = ResolveInclude(requestedSource); - includeData->m_content = Utils::ReadFile(includeData->m_fullPath, false, false); // using nullTerminate as true causes crash in here. Needed to use as false. + + // Do not null terminate the string + includeData->m_content = Utils::ReadFile(includeData->m_fullPath, false, false); shaderc_include_result* result = &includeData->result; result->content = includeData->m_content.Data(); @@ -70,4 +124,5 @@ namespace OpenVulkano if (std::filesystem::exists(path)) return path; else throw std::runtime_error("Failed to resolve include '" + requestedSource + "'!"); } +#endif } diff --git a/openVulkanoCpp/Shader/ShaderCompiler.hpp b/openVulkanoCpp/Shader/ShaderCompiler.hpp index 6eb0df0..ae3d561 100644 --- a/openVulkanoCpp/Shader/ShaderCompiler.hpp +++ b/openVulkanoCpp/Shader/ShaderCompiler.hpp @@ -3,35 +3,10 @@ #include "Base/Utils.hpp" #include "Base/Wrapper.hpp" -#include -#include #include namespace OpenVulkano { - class ShaderIncluder : public shaderc::CompileOptions::IncluderInterface - { - struct IncludeData - { - shaderc_include_result result = {}; - std::string m_fullPath; - Array m_content; - }; - public: - ShaderIncluder(const std::string& path); - ~ShaderIncluder() override = default; - - shaderc_include_result* GetInclude(const char* requestedSource, shaderc_include_type type, - const char* requestingSource, uint64_t includeDepth) override; - void ReleaseInclude(shaderc_include_result* data) override; - - private: - std::string ResolveInclude(const std::string& requestedSource) const; - - private: - std::string m_includePath; - }; - class ShaderCompiler { public: @@ -40,10 +15,13 @@ namespace OpenVulkano * @param incPath - include path that will be used to resolve includes * @param entryPoint - the name of the void function in the shader * @param shaderStage - type of the shader that needs to be compiled - * @param bHaveIncludes - if incPath is empty, make it false */ - static Unique CompileGLSLToSpirv(const std::string& absPath, - const std::string& incPath, const std::string& entryPoint, - shaderc_shader_kind shaderStage, bool bHaveIncludes); + static Array CompileGLSLToSpirv(const std::string& absPath, bool hasIncludes, + const std::string& incPath = std::string(), const std::string& entryPoint = "main") +#if defined(HAS_SHADERC) + ; +#else + { throw std::runtime_error("Shader compiler is not available on this platform"); } +#endif }; } \ No newline at end of file diff --git a/openVulkanoCpp/Shader/test.vert b/openVulkanoCpp/Shader/test.vert deleted file mode 100644 index 3d16cda..0000000 --- a/openVulkanoCpp/Shader/test.vert +++ /dev/null @@ -1,8 +0,0 @@ -#version 460 -#extension GL_KHR_vulkan_glsl : enable - -#include "test1.glsl" - -void main() -{ -}; \ No newline at end of file diff --git a/openVulkanoCpp/Shader/test1.glsl b/openVulkanoCpp/Shader/test1.glsl deleted file mode 100644 index 92671bc..0000000 --- a/openVulkanoCpp/Shader/test1.glsl +++ /dev/null @@ -1,3 +0,0 @@ -void testfunction() -{ -}; \ No newline at end of file