void ShaderCompiler::compilePass( const char* shd_path, bool is_vertex_shader, const char* pass, int define_mask, const Lumix::ShaderCombinations::Defines& all_defines) { for (int mask = 0; mask < 1 << Lumix::lengthOf(all_defines); ++mask) { if ((mask & (~define_mask)) == 0) { updateNotifications(); char basename[Lumix::MAX_PATH_LENGTH]; Lumix::PathUtils::getBasename(basename, sizeof(basename), shd_path); const char* source_path = StringBuilder<Lumix::MAX_PATH_LENGTH>( "\"shaders/", basename, is_vertex_shader ? "_vs.sc\"" : "_fs.sc\""); char out_path[Lumix::MAX_PATH_LENGTH]; Lumix::copyString(out_path, m_editor.getBasePath()); Lumix::catString(out_path, "/shaders/compiled/"); Lumix::catString(out_path, basename); Lumix::catString(out_path, "_"); Lumix::catString(out_path, StringBuilder<30>(pass, mask)); Lumix::catString(out_path, is_vertex_shader ? "_vs.shb" : "_fs.shb"); StringBuilder<1024> args(" -f "); args << source_path << " -o \"" << out_path << "\" --depends --platform windows --type " << (is_vertex_shader ? "vertex --profile vs_4_0" : "fragment --profile ps_4_0") << " -D " << pass; for (int i = 0; i < Lumix::lengthOf(all_defines); ++i) { if (mask & (1 << i)) { args << " -D " << getRenderer().getShaderDefine(all_defines[i]); } } StringBuilder<Lumix::MAX_PATH_LENGTH> cmd(m_editor.getBasePath(), "/shaders/shaderc.exe"); Lumix::deleteFile(out_path); auto* process = Lumix::createProcess(cmd, args, m_editor.getAllocator()); if (!process) { Lumix::g_log_error.log("shader compiler") << "Could not execute command: " << cmd; } else { auto& p = m_processes.pushEmpty(); p.process = process; Lumix::copyString(p.path, out_path); } } } }
void ShaderCompiler::update() { PROFILE_FUNCTION(); for (int i = 0; i < m_processes.size(); ++i) { if (PlatformInterface::isProcessFinished(*m_processes[i].process)) { bool failed = PlatformInterface::getProcessExitCode(*m_processes[i].process) != 0; if (failed) { if (strstr(m_processes[i].path, "imgui") != nullptr) { Lumix::messageBox("Could not compile imgui shader"); } char buf[1024]; int read; Lumix::g_log_error.log("Editor") << m_processes[i].path; while ((read = PlatformInterface::getProcessOutput( *m_processes[i].process, buf, sizeof(buf) - 1)) > 0) { buf[read] = 0; Lumix::g_log_error.log("Editor") << buf; } } PlatformInterface::destroyProcess(*m_processes[i].process); m_processes.eraseFast(i); updateNotifications(); if (m_processes.empty() && m_changed_files.empty()) { reloadShaders(); parseDependencies(); } } } m_is_compiling = !m_processes.empty() || !m_to_compile.empty(); m_app.getAssetBrowser()->enableUpdate(!m_is_compiling); processChangedFiles(); if (m_processes.size() < 4 && !m_to_compile.empty()) { compile(m_to_compile.back().c_str()); m_to_compile.pop(); } }
void ShaderCompiler::update(float) { PROFILE_FUNCTION(); for (int i = 0; i < m_processes.size(); ++i) { if (Lumix::isProcessFinished(*m_processes[i].process)) { bool failed = Lumix::getProcessExitCode(*m_processes[i].process) != 0; if (failed) { if (strstr(m_processes[i].path, "imgui") != nullptr) { Lumix::messageBox("Could not compile imgui shader"); } char buf[1024]; int read; while ((read = Lumix::getProcessOutput(*m_processes[i].process, buf, sizeof(buf) - 1)) > 0) { buf[read] = 0; Lumix::g_log_error.log("shader compiler") << buf; } } Lumix::destroyProcess(*m_processes[i].process); m_processes.eraseFast(i); updateNotifications(); if (m_processes.empty() && m_changed_files.empty()) { reloadShaders(); parseDependencies(); } } } m_is_compiling = !m_processes.empty(); processChangedFiles(); }
void ShaderCompiler::compilePass(const char* shd_path, bool is_vertex_shader, const char* pass, int define_mask, const Lumix::ShaderCombinations::Defines& all_defines) { const char* base_path = m_editor.getEngine().getDiskFileDevice()->getBasePath(); bool is_opengl = getRenderer().isOpenGL(); for (int mask = 0; mask < 1 << Lumix::lengthOf(all_defines); ++mask) { if ((mask & (~define_mask)) == 0) { updateNotifications(); char basename[Lumix::MAX_PATH_LENGTH]; Lumix::PathUtils::getBasename(basename, sizeof(basename), shd_path); Lumix::StaticString<Lumix::MAX_PATH_LENGTH> source_path ( "\"shaders/", basename, is_vertex_shader ? "_vs.sc\"" : "_fs.sc\""); char out_path[Lumix::MAX_PATH_LENGTH]; Lumix::copyString(out_path, base_path); Lumix::catString(out_path, "/shaders/compiled"); Lumix::catString(out_path, is_opengl ? "_gl/" : "/"); Lumix::catString(out_path, basename); Lumix::catString(out_path, "_"); Lumix::catString(out_path, Lumix::StaticString<30>(pass, mask)); Lumix::catString(out_path, is_vertex_shader ? "_vs.shb" : "_fs.shb"); Lumix::StaticString<1024> args(" -f "); args << source_path << " -o \"" << out_path << "\" --depends "; if (getRenderer().isOpenGL()) { args << "--platform linux --profile 140 "; } else { args << "--platform windows " << (is_vertex_shader ? "--profile vs_5_0" : "--profile ps_5_0"); } args << " --type " << (is_vertex_shader ? "vertex -O3" : "fragment -O3") << " --define " << pass << ";"; for (int i = 0; i < Lumix::lengthOf(all_defines); ++i) { if (mask & (1 << i)) { args << getRenderer().getShaderDefine(all_defines[i]) << ";"; } } #ifdef _WIN32 Lumix::StaticString<Lumix::MAX_PATH_LENGTH> cmd(base_path, "/shaders/shaderc.exe"); #elif defined __linux__ Lumix::StaticString<Lumix::MAX_PATH_LENGTH> cmd(base_path, "/shaders/shaderc"); #else #error Platform not supported #endif PlatformInterface::deleteFile(out_path); auto* process = PlatformInterface::createProcess(cmd, args, m_editor.getAllocator()); if (!process) { Lumix::g_log_error.log("Editor") << "Could not execute command: " << cmd; } else { auto& p = m_processes.emplace(); p.process = process; Lumix::copyString(p.path, out_path); } } } }