740{
741 namespace fs = std::filesystem;
742
743 if (!is_command_available("glslc")) {
745 "glslc compiler not found in PATH. Install Vulkan SDK or enable MAYAFLUX_USE_SHADERC");
746 return {};
747 }
748
749 fs::path temp_dir = fs::temp_directory_path();
750 fs::path glsl_temp = temp_dir / "mayaflux_shader_temp.glsl";
751 fs::path spirv_temp = temp_dir / "mayaflux_shader_temp.spv";
752
753 {
754 std::ofstream out(glsl_temp);
755 if (!out.is_open()) {
757 "Failed to create temporary GLSL file: '{}'", glsl_temp.string());
758 return {};
759 }
760 out << glsl_source;
761 }
762
763 std::string stage_flag;
764 switch (stage) {
765 case vk::ShaderStageFlagBits::eVertex: stage_flag = "-fshader-stage=vertex"; break;
766 case vk::ShaderStageFlagBits::eFragment: stage_flag = "-fshader-stage=fragment"; break;
767 case vk::ShaderStageFlagBits::eCompute: stage_flag = "-fshader-stage=compute"; break;
768 case vk::ShaderStageFlagBits::eGeometry: stage_flag = "-fshader-stage=geometry"; break;
769 case vk::ShaderStageFlagBits::eTessellationControl: stage_flag = "-fshader-stage=tesscontrol"; break;
770 case vk::ShaderStageFlagBits::eTessellationEvaluation: stage_flag = "-fshader-stage=tesseval"; break;
771 default:
773 "Unsupported shader stage for external compilation: {}", vk::to_string(stage));
774 fs::remove(glsl_temp);
775 return {};
776 }
777
778#if defined(MAYAFLUX_PLATFORM_WINDOWS)
779 std::string cmd = "glslc " + stage_flag + " \"" + glsl_temp.string() + "\" -o \"" + spirv_temp.string() + "\"";
780#else
781 std::string cmd = "glslc " + stage_flag + " '" + glsl_temp.string() + "' -o '" + spirv_temp.string() + "'";
782#endif
783
784 for (const auto& dir : include_directories) {
785#if defined(MAYAFLUX_PLATFORM_WINDOWS)
786 cmd += " -I\"" + dir + "\"";
787#else
788 cmd += " -I'" + dir + "'";
789#endif
790 }
791
792 for (const auto& [name, value] : defines) {
793 cmd += " -D" + name;
794 if (!value.empty()) {
795 cmd += "=" + value;
796 }
797 }
798
799 std::string null_device = get_null_device();
800
802 "Invoking external glslc : {}", cmd);
803
804 int result = std::system(cmd.c_str());
805
806 fs::remove(glsl_temp);
807
808 if (result != 0) {
810 "External glslc compilation failed (exit code: {})", result);
812 "Make sure Vulkan SDK is installed or enable MAYAFLUX_USE_SHADERC for runtime compilation");
813 fs::remove(spirv_temp);
814 return {};
815 }
816
818
819 fs::remove(spirv_temp);
820
821 if (!spirv_code.empty()) {
823 "Compiled GLSL ({} stage) via external glslc -> {} bytes SPIR-V",
824 vk::to_string(stage), spirv_code.size() * 4);
825 }
826
827 return spirv_code;
828}
#define MF_INFO(comp, ctx,...)
#define MF_ERROR(comp, ctx,...)
#define MF_DEBUG(comp, ctx,...)
static std::vector< uint32_t > read_spirv_file(const std::string &filepath)
Read binary file into vector.
@ GraphicsBackend
Graphics/visual rendering backend (Vulkan, OpenGL)
@ Core
Core engine, backend, subsystems.