818{
819 namespace fs = std::filesystem;
820
821 if (!is_command_available("glslc")) {
823 "glslc compiler not found in PATH. Install Vulkan SDK or enable MAYAFLUX_USE_SHADERC");
824 return {};
825 }
826
827 fs::path temp_dir = fs::temp_directory_path();
828 fs::path glsl_temp = temp_dir / "mayaflux_shader_temp.glsl";
829 fs::path spirv_temp = temp_dir / "mayaflux_shader_temp.spv";
830
831 {
832 std::ofstream out(glsl_temp);
833 if (!out.is_open()) {
835 "Failed to create temporary GLSL file: '{}'", glsl_temp.string());
836 return {};
837 }
838 out << glsl_source;
839 }
840
841 std::string stage_flag;
842 switch (stage) {
843 case vk::ShaderStageFlagBits::eVertex:
844 stage_flag = "-fshader-stage=vertex";
845 break;
846 case vk::ShaderStageFlagBits::eFragment:
847 stage_flag = "-fshader-stage=fragment";
848 break;
849 case vk::ShaderStageFlagBits::eCompute:
850 stage_flag = "-fshader-stage=compute";
851 break;
852 case vk::ShaderStageFlagBits::eGeometry:
853 stage_flag = "-fshader-stage=geometry";
854 break;
855 case vk::ShaderStageFlagBits::eTessellationControl:
856 stage_flag = "-fshader-stage=tesscontrol";
857 break;
858 case vk::ShaderStageFlagBits::eTessellationEvaluation:
859 stage_flag = "-fshader-stage=tesseval";
860 break;
861 case vk::ShaderStageFlagBits::eMeshEXT:
862 stage_flag = "-fshader-stage=mesh";
863 break;
864 case vk::ShaderStageFlagBits::eTaskEXT:
865 stage_flag = "-fshader-stage=task";
866 break;
867 default:
869 "Unsupported shader stage for external compilation: {}", vk::to_string(stage));
870 fs::remove(glsl_temp);
871 return {};
872 }
873
874#if defined(MAYAFLUX_PLATFORM_WINDOWS)
875 std::string
cmd =
"glslc " + stage_flag +
" \"" + glsl_temp.string() +
"\" -o \"" + spirv_temp.string() +
"\"";
876#else
877 std::string
cmd =
"glslc " + stage_flag +
" '" + glsl_temp.string() +
"' -o '" + spirv_temp.string() +
"'";
878#endif
879
880 for (const auto& dir : include_directories) {
881#if defined(MAYAFLUX_PLATFORM_WINDOWS)
882 cmd +=
" -I\"" + dir +
"\"";
883#else
884 cmd +=
" -I'" + dir +
"'";
885#endif
886 }
887
888 for (const auto& [name, value] : defines) {
890 if (!value.empty()) {
892 }
893 }
894
895 std::string null_device = get_null_device();
896
898 "Invoking external glslc : {}",
cmd);
899
900 int result = std::system(
cmd.c_str());
901
902 fs::remove(glsl_temp);
903
904 if (result != 0) {
906 "External glslc compilation failed (exit code: {})", result);
908 "Make sure Vulkan SDK is installed or enable MAYAFLUX_USE_SHADERC for runtime compilation");
909 fs::remove(spirv_temp);
910 return {};
911 }
912
914
915 fs::remove(spirv_temp);
916
917 if (!spirv_code.empty()) {
919 "Compiled GLSL ({} stage) via external glslc -> {} bytes SPIR-V",
920 vk::to_string(stage), spirv_code.size() * 4);
921 }
922
923 return spirv_code;
924}
#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.