From 2b773101c822fbad217b5df478011c5c9284f32d Mon Sep 17 00:00:00 2001 From: Caleb Cornett Date: Sat, 14 Jan 2023 23:34:55 -0500 Subject: [PATCH] Added shader cross-compiler using glslc and spirv-cross --- shadercompiler/Program.cs | 105 +++++++++++++++++++++++++++++++++ shadercompiler/refreshc.csproj | 9 +++ 2 files changed, 114 insertions(+) create mode 100644 shadercompiler/Program.cs create mode 100644 shadercompiler/refreshc.csproj diff --git a/shadercompiler/Program.cs b/shadercompiler/Program.cs new file mode 100644 index 0000000..ae2a780 --- /dev/null +++ b/shadercompiler/Program.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; +using System.Diagnostics; + +partial class Program +{ + public static int Main(string[] args) + { + if (args.Length < 2) + { + Console.WriteLine("Usage: refreshc "); + return 1; + } + + string glslPath = args[0]; + string outputDir = args[1]; + + if (!ValidateArgs(glslPath, outputDir)) + { + return 1; + } + + string shaderName = Path.GetFileNameWithoutExtension(glslPath); + string shaderType = Path.GetExtension(glslPath); + string spirvPath = Path.Combine(outputDir, $"{shaderName}.spv"); + + if (CompileGlslToSpirv(glslPath, shaderName, spirvPath) != 0) + { + return 1; + } + + string hlslPath = Path.Combine(outputDir, $"{shaderName}.hlsl"); + if (TranslateSpirvToHlsl(spirvPath, hlslPath) != 0) + { + return 1; + } + + // FIXME: Is there a cross-platform way to compile HLSL to DXBC? + +#if PS5 + if (TranslateHlslToPS5(hlslPath, shaderName, shaderType, outputDir) != 0) + { + return 1; + } +#endif + + return 0; + } + + static bool ValidateArgs(string glslPath, string outputDir) + { + if (!File.Exists(glslPath)) + { + Console.WriteLine($"refreshc: glsl source file ({glslPath}) does not exist"); + return false; + } + + string ext = Path.GetExtension(glslPath); + if (ext != ".vert" && ext != ".frag" && ext != ".comp") + { + Console.WriteLine("refreshc: Expected glsl source file with extension '.vert', '.frag', or '.comp'"); + return false; + } + + if (!Directory.Exists(outputDir)) + { + Console.WriteLine($"refreshc: Output directory ({outputDir}) does not exist"); + return false; + } + + return true; + } + + static int CompileGlslToSpirv(string glslPath, string shaderName, string outputPath) + { + Process glslc = Process.Start( + "glslc", + $"{glslPath} -o {outputPath}" + ); + glslc.WaitForExit(); + if (glslc.ExitCode != 0) + { + Console.WriteLine($"refreshc: Could not compile GLSL code"); + return 1; + } + + return 0; + } + + static int TranslateSpirvToHlsl(string spirvPath, string outputPath) + { + Process spirvcross = Process.Start( + "spirv-cross", + $"{spirvPath} --hlsl --shader-model 50 --output {outputPath}" + ); + spirvcross.WaitForExit(); + if (spirvcross.ExitCode != 0) + { + Console.WriteLine($"refreshc: Could not translate SPIR-V to HLSL"); + return 1; + } + + return 0; + } +} diff --git a/shadercompiler/refreshc.csproj b/shadercompiler/refreshc.csproj new file mode 100644 index 0000000..cce8a4b --- /dev/null +++ b/shadercompiler/refreshc.csproj @@ -0,0 +1,9 @@ + + + + Exe + net7.0 + refreshc + + +