#include "ShaderCompiler.hpp" namespace OpenVulkano { Unique ShaderCompiler::CompileGLSLToSpirv(const std::string& absPath, const std::string& incPath, const std::string& entryPoint, shaderc_shader_kind shaderStage, bool bHaveIncludes) { Array file = Utils::ReadFile(absPath, false, true); #if defined(_DEBUG) printf("Compiling shader: %s\n", absPath.c_str()); printf("%s\n", file.Data() + 1); #endif shaderc::Compiler shaderCompiler; shaderc::CompileOptions options; if (bHaveIncludes) options.SetIncluder(std::make_unique(incPath)); options.SetSourceLanguage(shaderc_source_language_glsl); options.SetSuppressWarnings(); shaderc::PreprocessedSourceCompilationResult preResult = shaderCompiler.PreprocessGlsl(file.Data(), shaderStage, entryPoint.c_str(), options); if (preResult.GetCompilationStatus() != shaderc_compilation_status_success) { throw std::runtime_error("Failed to preprocess shader: " + preResult.GetErrorMessage()); return nullptr; } shaderc::CompilationResult result = shaderCompiler.CompileGlslToSpv(static_cast(preResult.begin()), shaderStage, "", options); if (result.GetCompilationStatus() != shaderc_compilation_status_success) { throw std::runtime_error("Failed to compile shader: " + result.GetErrorMessage()); return nullptr; } Unique spirv = std::make_unique((void*) result.begin()); return spirv; } ShaderIncluder::ShaderIncluder(const std::string& path) { // TODO : Add the path to your include folder m_includes.push_back(path); } shaderc_include_result* ShaderIncluder::GetInclude(const char* requested_source, shaderc_include_type type, const char* requesting_source, uint64_t include_depth) { const char* includePath = GetActualPath(requested_source); const char* content = RecordInclude(includePath); shaderc_include_result* result = new shaderc_include_result(); result->content = content; result->content_length = strlen(content); result->source_name = includePath; result->source_name_length = strlen(includePath); result->user_data = nullptr; return result; } void ShaderIncluder::ReleaseInclude(shaderc_include_result* data) { delete data; } std::string ShaderIncluder::ResolveInclude(const std::string requestedSource) { // Check if the file exists in the include paths for (const std::string& includePath: m_includes) { std::string path = includePath + requestedSource; return path; } return ""; } const char* ShaderIncluder::RecordInclude(const std::string& requestedSource) { Array data = Utils::ReadFile(requestedSource); char* result = new char[data.Size() + 1]; strcpy_s(result, data.Size(), data.Data()); return result; } const char* ShaderIncluder::GetActualPath(const std::string& requestedSource) { std::string includePath = ResolveInclude(requestedSource); char* result = new char[includePath.size() + 1]; strcpy_s(result, includePath.size(), includePath.c_str()); return result; } }