public void DoubleConstant_ParsedCorrectly() { var res = SpirvCompilation.CompileGlslToSpirv(@" #version 450 void main() { double x = 12.3; gl_Position = vec4(x); } ", "shader.vert", ShaderStages.Vertex, GlslCompileOptions.Default); var shader = SpirVGraph.Shader.Parse(res.SpirvBytes); #if DEBUG Console.WriteLine(shader); #endif var constants = shader.Instructions.Where(_ => _.OpCode == Op.OpConstant).Select(_ => (OpConstant)_).ToList(); foreach (var instruction in constants) { if (instruction.Value.Value.Type.OpCode == Op.OpTypeFloat && instruction.Value.Value.Type.SizeInWords == 2) { if (instruction.Value.Value.ToDouble() == 12.3) { return; } } } Assert.Fail("Didn't find Double constant in the shader code:\n" + shader); }
public void FindAllDecorations() { var map = new Dictionary <Op, HashSet <Decoration.Enumerant> >(); foreach (var shader in SampleShaders.EnumerateShaders()) { SpirvCompilationResult shaderBytes; try { (var shaderSource, var stage) = SampleShaders.LoadShader(shader, typeof(SampleShaders).Assembly); shaderBytes = SpirvCompilation.CompileGlslToSpirv(shaderSource, "shader.vk", stage, new GlslCompileOptions { Debug = true }); } catch (SpirvCompilationException exception) { continue; } var instructions = Shader.Parse(shaderBytes.SpirvBytes); //var decorates = instructions.Instructions // .Where(_ => _.OpCode == Op.OpDecorate) // .Select(_ => (OpDecorate) _); //foreach (var opDecorate in decorates) //{ // if (!map.TryGetValue(opDecorate.Target.Instruction.OpCode, out var set)) // { // set = new HashSet<Decoration.Enumerant>(); // map.Add(opDecorate.Target.Instruction.OpCode, set); // } // set.Add(opDecorate.Decoration.Value); //} var decorates = instructions.Instructions .Where(_ => _.OpCode == Op.OpMemberDecorate) .Select(_ => (OpMemberDecorate)_); foreach (var opDecorate in decorates) { if (!map.TryGetValue(opDecorate.StructureType.Instruction.OpCode, out var set)) { set = new HashSet <Decoration.Enumerant>(); map.Add(opDecorate.StructureType.Instruction.OpCode, set); } set.Add(opDecorate.Decoration.Value); } } foreach (var decorate in map) { Console.WriteLine($"{decorate.Key}:"); foreach (var enumerant in decorate.Value) { Console.WriteLine($" {enumerant}"); } } }
private static (byte[], Shader) CompileToBytecode(string vertexShaderText) { var vertex = SpirvCompilation.CompileGlslToSpirv(vertexShaderText, "vertex.glsl", ShaderStages.Vertex, new GlslCompileOptions { Debug = true }); return(vertex.SpirvBytes, Shader.Parse(vertex.SpirvBytes)); }
private byte[] CompileToSpirv( VesselShaderDescription shader, string fileName, ShaderStages stage) { GlslCompileOptions glslOptions = VesselShaderUtil.GetOptions(shader); string glsl = VesselShaderUtil.LoadGlsl(fileName); SpirvCompilationResult result = SpirvCompilation.CompileGlslToSpirv( glsl, fileName, stage, glslOptions); return(result.SpirvBytes); }
public void GlslToSpirv_Succeeds(string name, ShaderStages stage) { SpirvCompilationResult result = SpirvCompilation.CompileGlslToSpirv( TestUtil.LoadShaderText(name), name, stage, new GlslCompileOptions( false, new MacroDefinition("Name0", "Value0"), new MacroDefinition("Name1", "Value1"), new MacroDefinition("Name2"))); Assert.NotNull(result.SpirvBytes); Assert.True(result.SpirvBytes.Length > 4); Assert.True(result.SpirvBytes.Length % 4 == 0); }
private (Shader, Veldrid.Shader[]) CompileShaderForFieldSet(TypeStruct fieldSet) { var vertexShaderText = new VertexShaderTemplate(fieldSet).TransformText(); var(vertexBytes, shaderInstructions) = CompileToBytecode(vertexShaderText); var fragmentShaderText = new FragmentShaderTemplate().TransformText(); var fragment = SpirvCompilation.CompileGlslToSpirv(fragmentShaderText, "fragment.glsl", ShaderStages.Fragment, new GlslCompileOptions { Debug = true }); var shaders = ResourceFactory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, vertexBytes, "main"), new ShaderDescription(ShaderStages.Fragment, fragment.SpirvBytes, "main")); foreach (var shader in shaders) { Disposables.Add(shader); } return(shaderInstructions, shaders); }
public void LoadSampleShader(string resource) { string text = null; using (var stream = this.GetType().Assembly.GetManifestResourceStream(resource)) { text = new StreamReader(stream).ReadToEnd(); } var stage = ShaderStages.Vertex; if (resource.EndsWith(".comp")) { stage = ShaderStages.Compute; } if (resource.EndsWith(".vert")) { stage = ShaderStages.Vertex; } if (resource.EndsWith(".frag")) { stage = ShaderStages.Fragment; } SpirvCompilationResult res; try { res = SpirvCompilation.CompileGlslToSpirv(text, resource, stage, GlslCompileOptions.Default); } catch (Exception ex) { Assert.Ignore(ex.Message); return; } var shader = SpirVGraph.Shader.Parse(res.SpirvBytes); #if DEBUG Console.WriteLine(shader); #endif }
public static byte[] CompileToBytecode(string vertexShaderText, ShaderStages stage = ShaderStages.Vertex, bool debug = true, bool throwOnError = false) { if (throwOnError) { var vertex = SpirvCompilation.CompileGlslToSpirv(vertexShaderText, "shader.vk", stage, new GlslCompileOptions { Debug = debug }); return(vertex.SpirvBytes); } try { var vertex = SpirvCompilation.CompileGlslToSpirv(vertexShaderText, "shader.vk", stage, new GlslCompileOptions { Debug = debug }); return(vertex.SpirvBytes); } catch (SpirvCompilationException exception) { Assert.Ignore(exception.Message); return(null); } }
private static void CompileAll(string inputDirectory, string outputDirectory) { Directory.CreateDirectory(outputDirectory); IEnumerable <string> files = Directory.EnumerateFiles(inputDirectory); var shaderSets = from path in files let vert = path.EndsWith("vert") let frag = path.EndsWith("frag") where vert || frag let name = Path.GetFileNameWithoutExtension(path) group(path, vert, frag) by name into g where g.Count() == 2 select new { Name = g.Key, Vertex = g.FirstOrDefault(x => x.vert).path, Fragment = g.FirstOrDefault(x => x.frag).path, }; foreach (var shaderSet in shaderSets) { string outputBase = Path.Combine(outputDirectory, shaderSet.Name); byte[] vs = File.ReadAllBytes(shaderSet.Vertex); byte[] fs = File.ReadAllBytes(shaderSet.Fragment); string vsSource = Encoding.UTF8.GetString(vs); string fsSource = Encoding.UTF8.GetString(fs); var debugCompileOptions = new GlslCompileOptions(debug: true); var vsSpvDebugOutput = SpirvCompilation.CompileGlslToSpirv( vsSource, string.Empty, ShaderStages.Vertex, debugCompileOptions); var fsSpvDebugOutput = SpirvCompilation.CompileGlslToSpirv( fsSource, string.Empty, ShaderStages.Fragment, debugCompileOptions); var releaseCompileOptions = new GlslCompileOptions(debug: false); var vsSpvReleaseOutput = SpirvCompilation.CompileGlslToSpirv( vsSource, string.Empty, ShaderStages.Vertex, releaseCompileOptions); var fsSpvReleaseOutput = SpirvCompilation.CompileGlslToSpirv( fsSource, string.Empty, ShaderStages.Fragment, releaseCompileOptions); File.WriteAllBytes(outputBase + "-vertex.450.glsl.spv", vsSpvReleaseOutput.SpirvBytes); File.WriteAllBytes(outputBase + "-fragment.450.glsl.spv", fsSpvDebugOutput.SpirvBytes); var glCompileOptions = new CrossCompileOptions(fixClipSpaceZ: true, invertVertexOutputY: false); var glslResult = SpirvCompilation.CompileVertexFragment( vsSpvDebugOutput.SpirvBytes, fsSpvDebugOutput.SpirvBytes, CrossCompileTarget.GLSL, glCompileOptions); File.WriteAllText(outputBase + "-vertex.330.glsl", glslResult.VertexShader); File.WriteAllText(outputBase + "-fragment.330.glsl", glslResult.FragmentShader); var esslResult = SpirvCompilation.CompileVertexFragment( vsSpvDebugOutput.SpirvBytes, fsSpvDebugOutput.SpirvBytes, CrossCompileTarget.ESSL, glCompileOptions); File.WriteAllText(outputBase + "-vertex.300.glsles", glslResult.VertexShader); File.WriteAllText(outputBase + "-fragment.300.glsles", glslResult.FragmentShader); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { var hlslDebugOutput = SpirvCompilation.CompileVertexFragment( vsSpvDebugOutput.SpirvBytes, fsSpvDebugOutput.SpirvBytes, CrossCompileTarget.HLSL); File.WriteAllText(outputBase + "-vertex.hlsl", hlslDebugOutput.VertexShader); File.WriteAllText(outputBase + "-fragment.hlsl", hlslDebugOutput.FragmentShader); var hlslReleaseOutput = SpirvCompilation.CompileVertexFragment( vsSpvReleaseOutput.SpirvBytes, fsSpvReleaseOutput.SpirvBytes, CrossCompileTarget.HLSL); byte[] vertBytes = Encoding.UTF8.GetBytes(hlslReleaseOutput.VertexShader); byte[] fragBytes = Encoding.UTF8.GetBytes(hlslReleaseOutput.FragmentShader); File.WriteAllBytes(outputBase + "-vertex.hlsl.bytes", CompileHlsl(ShaderStages.Vertex, vertBytes)); File.WriteAllBytes(outputBase + "-fragment.hlsl.bytes", CompileHlsl(ShaderStages.Fragment, fragBytes)); } } }
public ShaderSet(AssetFactoryState assets, RawShaderSet raw) { var graphics = assets.Graphics; Shader?Compile(ShaderStages stage, string?glsl) { return(glsl == null ? null : graphics.Device.ResourceFactory.CreateShader(new ShaderDescription(stage, SpirvCompilation.CompileGlslToSpirv(glsl, stage.ToString(), stage, GlslCompileOptions.Default).SpirvBytes, "main"))); } Vertex = Compile(ShaderStages.Vertex, raw.Vertex); Geometry = Compile(ShaderStages.Geometry, raw.Geometry); TessellationControl = Compile(ShaderStages.TessellationControl, raw.TessellationControl); TessellationEvaluation = Compile(ShaderStages.TessellationEvaluation, raw.TessellationEvaluation); Fragment = Compile(ShaderStages.Fragment, raw.Fragment); Compute = Compile(ShaderStages.Compute, raw.Compute); var vertexElements = Vertex == null ? new VertexElementDescription[0] : VertexInputPattern.Matches(raw.Vertex !).Select(x => new VertexElementDescription(x.Groups["name"].Value, VertexElementSemantic.Position, x.Groups["type"].Value switch { "ivec4" => VertexElementFormat.Int4, _ => throw new NotImplementedException() }, uint.Parse(x.Groups["offset"].Value)