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 static (Shader vs, Shader fs, SpecializationConstant[] specializations) LoadSPIRV( GraphicsDevice gd, ResourceFactory factory, string vertexShaderName, string fragmentShaderName, ReadOnlySpan <SpecializationConstant> specializations) { byte[] vsBytes = LoadBytecode(GraphicsBackend.Vulkan, vertexShaderName, ShaderStages.Vertex); byte[] fsBytes = LoadBytecode(GraphicsBackend.Vulkan, fragmentShaderName, ShaderStages.Fragment); bool debug = false; #if DEBUG debug = true; #endif CrossCompileOptions options = GetOptions(gd, specializations); var dst = SpirvCompilation.CompileVertexFragment(vsBytes, fsBytes, CrossCompileTarget.HLSL); Shader[] shaders = factory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, vsBytes, "main", debug), new ShaderDescription(ShaderStages.Fragment, fsBytes, "main", debug), options); Shader vs = shaders[0]; Shader fs = shaders[1]; vs.Name = vertexShaderName + "-Vertex"; fs.Name = fragmentShaderName + "-Fragment"; return(vs, fs, options.Specializations); }
public void ReflectionFromSpirv_Succeeds( string vertex, string fragment, VertexElementDescription[] verts, ResourceLayoutDescription[] layouts) { byte[] vsBytes = TestUtil.LoadBytes(vertex); byte[] fsBytes = TestUtil.LoadBytes(fragment); VertexFragmentCompilationResult result = SpirvCompilation.CompileVertexFragment( vsBytes, fsBytes, CrossCompileTarget.HLSL); VertexElementDescription[] reflectedVerts = result.Reflection.VertexElements; Assert.Equal(verts.Length, reflectedVerts.Length); for (int i = 0; i < verts.Length; i++) { Assert.Equal(verts[i], reflectedVerts[i]); } ResourceLayoutDescription[] reflectedLayouts = result.Reflection.ResourceLayouts; Assert.Equal(layouts.Length, reflectedLayouts.Length); for (int i = 0; i < layouts.Length; i++) { ResourceLayoutDescription layout = layouts[i]; ResourceLayoutDescription reflectedLayout = reflectedLayouts[i]; Assert.Equal(layout.Elements.Length, reflectedLayout.Elements.Length); for (int j = 0; j < layout.Elements.Length; j++) { Assert.Equal(layout.Elements[j], reflectedLayout.Elements[j]); } } }
public void ComputeSucceeds(string cs, CrossCompileTarget target) { byte[] csBytes = TestUtil.LoadBytes(cs); ComputeCompilationResult result = SpirvCompilation.CompileCompute(csBytes, target); Assert.NotNull(result.ComputeShader); }
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)); }
public void CompilationFails(string vs, string fs, CrossCompileTarget target) { byte[] vsBytes = TestUtil.LoadBytes(vs); byte[] fsBytes = TestUtil.LoadBytes(fs); Assert.Throws <SpirvCompilationException>(() => SpirvCompilation.CompileVertexFragment( vsBytes, fsBytes, target, new CrossCompileOptions(false, false))); }
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 string[] CompileCompute(VesselShaderDescription shader) { List <string> generatedFiles = new List <string>(); var csBytes = CompileToSpirv(shader, shader.Shaders[0].FileName, ShaderStages.Compute); // Generate metadata for HLSL, cuz we want to know the semantics since theyre important on HLSL var crossData = SpirvCompilation.CompileCompute(csBytes, CrossCompileTarget.HLSL); WriteShaderBinary( shader.Name + ".shdr", new byte[][] { csBytes }, crossData.Reflection); Console.WriteLine($"Successfully compiled \"{Path.GetFileNameWithoutExtension(shader.Shaders[0].FileName)}\" as a Compute shader!"); return(generatedFiles.ToArray()); }
public void VertexFragmentSucceeds(string vs, string fs, CrossCompileTarget target) { byte[] vsBytes = TestUtil.LoadBytes(vs); byte[] fsBytes = TestUtil.LoadBytes(fs); SpecializationConstant[] specializations = { new SpecializationConstant(100, 125u), new SpecializationConstant(101, true), new SpecializationConstant(102, 0.75f), }; VertexFragmentCompilationResult result = SpirvCompilation.CompileVertexFragment( vsBytes, fsBytes, target, new CrossCompileOptions(false, false, specializations)); Assert.NotNull(result.VertexShader); Assert.NotNull(result.FragmentShader); }
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); } }
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)
private string[] CompileVertexFragment(VesselShaderDescription shader) { List <string> generatedFiles = new List <string>(); List <Exception> compilationExceptions = new List <Exception>(); byte[] vsBytes = null; byte[] fsBytes = null; // Compile vertex shader string vertexFileName = shader.Shaders.FirstOrDefault(vsd => vsd.Stage == ShaderStages.Vertex).FileName; if (vertexFileName != null) { try { vsBytes = CompileToSpirv(shader, vertexFileName, ShaderStages.Vertex); } catch (Exception e) { compilationExceptions.Add(e); } } // Compile fragment shader string fragmentFileName = shader.Shaders.FirstOrDefault(vsd => vsd.Stage == ShaderStages.Fragment).FileName; if (fragmentFileName != null) { try { fsBytes = CompileToSpirv(shader, fragmentFileName, ShaderStages.Fragment); } catch (Exception e) { compilationExceptions.Add(e); } } if (compilationExceptions.Count > 0) { throw new AggregateException( $"Errors were encountered when compiling from GLSL to SPIR-V.", compilationExceptions); } try { // Generate reflection data VertexFragmentCompilationResult result = SpirvCompilation.CompileVertexFragment(vsBytes, fsBytes, CrossCompileTarget.HLSL); WriteShaderBinary( shader.Name + ".shdr", new byte[][] { vsBytes, fsBytes }, result.Reflection); } catch (Exception e) { compilationExceptions.Add(e); } if (compilationExceptions.Count > 0) { throw new AggregateException($"Errors were encountered when compiling shader variant(s).", compilationExceptions); } Console.WriteLine($"Successfully compiled \"{Path.GetFileNameWithoutExtension(shader.Shaders[0].FileName)}\" as a Vertex, Fragment pair shader!"); return(generatedFiles.ToArray()); }
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)); } } }
private static void GetOrCreateCachedShaders( ResourceFactory factory, string shaderName, bool debug, out byte[] vsBytes, out byte[] fsBytes) { const string shaderCacheFolder = "ShaderCache"; var backendType = factory.BackendType; var targetExtension = backendType.ToString().ToLowerInvariant(); if (!Directory.Exists(shaderCacheFolder)) { Directory.CreateDirectory(shaderCacheFolder); } var vsSpvName = $"OpenSage.Assets.Shaders.{shaderName}.vert.spv"; var fsSpvName = $"OpenSage.Assets.Shaders.{shaderName}.frag.spv"; var vsSpvBytes = ReadSpvShader(vsSpvName); var fsSpvBytes = ReadSpvShader(fsSpvName); var vsSpvHash = GetShaderHash(vsSpvBytes); var fsSpvHash = GetShaderHash(fsSpvBytes); // Check that SPIR-V files on disk match what's in the assembly. var vsCacheFilePath = Path.Combine(shaderCacheFolder, $"OpenSage.Assets.Shaders.{shaderName}.vert.{vsSpvHash}.{targetExtension}"); var fsCacheFilePath = Path.Combine(shaderCacheFolder, $"OpenSage.Assets.Shaders.{shaderName}.frag.{fsSpvHash}.{targetExtension}"); if (File.Exists(vsCacheFilePath) && File.Exists(fsCacheFilePath)) { // Cache is valid - use it. vsBytes = File.ReadAllBytes(vsCacheFilePath); fsBytes = File.ReadAllBytes(fsCacheFilePath); return; } // Cache is invalid or doesn't exist - do cross-compilation. if (backendType == GraphicsBackend.Vulkan) { File.WriteAllBytes(vsCacheFilePath, vsSpvBytes); File.WriteAllBytes(fsCacheFilePath, fsSpvBytes); vsBytes = vsSpvBytes; fsBytes = fsSpvBytes; return; } var compilationTarget = GetCompilationTarget(backendType); var compilationResult = SpirvCompilation.CompileVertexFragment( vsSpvBytes, fsSpvBytes, compilationTarget, new CrossCompileOptions()); switch (backendType) { case GraphicsBackend.Direct3D11: vsBytes = CompileHlsl(compilationResult.VertexShader, "vs_5_0", debug); fsBytes = CompileHlsl(compilationResult.FragmentShader, "ps_5_0", debug); break; case GraphicsBackend.OpenGL: case GraphicsBackend.OpenGLES: vsBytes = Encoding.ASCII.GetBytes(compilationResult.VertexShader); fsBytes = Encoding.ASCII.GetBytes(compilationResult.FragmentShader); break; case GraphicsBackend.Metal: // TODO: Compile to IR. vsBytes = Encoding.UTF8.GetBytes(compilationResult.VertexShader); fsBytes = Encoding.UTF8.GetBytes(compilationResult.FragmentShader); break; default: throw new InvalidOperationException(); } File.WriteAllBytes(vsCacheFilePath, vsBytes); File.WriteAllBytes(fsCacheFilePath, fsBytes); }
public static ShaderCacheFile GetOrCreateCachedShaders( ResourceFactory factory, Assembly shaderAssembly, string shaderName) { const string shaderCacheFolder = "ShaderCache"; var backendType = factory.BackendType; var targetExtension = backendType.ToString().ToLowerInvariant(); if (!Directory.Exists(shaderCacheFolder)) { Directory.CreateDirectory(shaderCacheFolder); } var vsSpvBytes = ReadShaderSpv(shaderAssembly, shaderName, "vert"); var fsSpvBytes = ReadShaderSpv(shaderAssembly, shaderName, "frag"); var spvHash = GetShaderHash(vsSpvBytes, fsSpvBytes); // Look for cached shader file on disk match the input SPIR-V shaders. var cacheFilePath = Path.Combine(shaderCacheFolder, $"OpenSage.Assets.Shaders.{shaderName}.{spvHash}.{targetExtension}"); if (ShaderCacheFile.TryLoad(cacheFilePath, out var shaderCacheFile)) { // Cache is valid - use it. return(shaderCacheFile); } // Cache is invalid or doesn't exist - do cross-compilation. // For Vulkan, we don't actually need to do cross-compilation. But we do need to get reflection data. // So we cross-compile to HLSL, throw away the resulting HLSL, and use the reflection data. var compilationTarget = backendType == GraphicsBackend.Vulkan ? CrossCompileTarget.HLSL : GetCompilationTarget(backendType); var compilationResult = SpirvCompilation.CompileVertexFragment( vsSpvBytes, fsSpvBytes, compilationTarget, new CrossCompileOptions()); byte[] vsBytes, fsBytes; switch (backendType) { case GraphicsBackend.Vulkan: vsBytes = vsSpvBytes; fsBytes = fsSpvBytes; break; case GraphicsBackend.Direct3D11: vsBytes = CompileHlsl(compilationResult.VertexShader, "vs_5_0"); fsBytes = CompileHlsl(compilationResult.FragmentShader, "ps_5_0"); break; case GraphicsBackend.OpenGL: case GraphicsBackend.OpenGLES: vsBytes = Encoding.ASCII.GetBytes(compilationResult.VertexShader); fsBytes = Encoding.ASCII.GetBytes(compilationResult.FragmentShader); break; case GraphicsBackend.Metal: // TODO: Compile to IR. vsBytes = Encoding.UTF8.GetBytes(compilationResult.VertexShader); fsBytes = Encoding.UTF8.GetBytes(compilationResult.FragmentShader); break; default: throw new InvalidOperationException(); } var entryPoint = factory.BackendType == GraphicsBackend.Metal ? $"{EntryPoint}0" : EntryPoint; shaderCacheFile = new ShaderCacheFile( new ShaderDescription(ShaderStages.Vertex, vsBytes, entryPoint), new ShaderDescription(ShaderStages.Fragment, fsBytes, entryPoint), compilationResult.Reflection.ResourceLayouts); shaderCacheFile.Save(cacheFilePath); return(shaderCacheFile); }
protected override void CreateResources(ResourceFactory factory) { _particleBuffer = factory.CreateBuffer( new BufferDescription( (uint)Unsafe.SizeOf <ParticleInfo>() * ParticleCount, BufferUsage.StructuredBufferReadWrite, (uint)Unsafe.SizeOf <ParticleInfo>())); _screenSizeBuffer = factory.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer)); _computeShader = factory.CreateFromSpirv(new ShaderDescription( ShaderStages.Compute, ReadEmbeddedAssetBytes($"Compute.glsl"), "main")); ResourceLayout particleStorageLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ParticlesBuffer", ResourceKind.StructuredBufferReadWrite, ShaderStages.Compute))); ResourceLayout screenSizeLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ScreenSizeBuffer", ResourceKind.UniformBuffer, ShaderStages.Compute))); ComputePipelineDescription computePipelineDesc = new ComputePipelineDescription( _computeShader, new[] { particleStorageLayout, screenSizeLayout }, 1, 1, 1); _computePipeline = factory.CreateComputePipeline(ref computePipelineDesc); _computeResourceSet = factory.CreateResourceSet(new ResourceSetDescription(particleStorageLayout, _particleBuffer)); _computeScreenSizeResourceSet = factory.CreateResourceSet(new ResourceSetDescription(screenSizeLayout, _screenSizeBuffer)); var result = SpirvCompilation.CompileVertexFragment(ReadEmbeddedAssetBytes($"Vertex.glsl"), ReadEmbeddedAssetBytes($"Fragment.glsl"), CrossCompileTarget.MSL); var shaders = factory.CreateFromSpirv( new ShaderDescription( ShaderStages.Vertex, ReadEmbeddedAssetBytes($"Vertex.glsl"), "main"), new ShaderDescription( ShaderStages.Fragment, ReadEmbeddedAssetBytes($"Fragment.glsl"), "main")); ShaderSetDescription shaderSet = new ShaderSetDescription( Array.Empty <VertexLayoutDescription>(), shaders); particleStorageLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ParticlesBuffer", ResourceKind.StructuredBufferReadOnly, ShaderStages.Vertex))); screenSizeLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ScreenSizeBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex))); GraphicsPipelineDescription particleDrawPipelineDesc = new GraphicsPipelineDescription( BlendStateDescription.SingleOverrideBlend, DepthStencilStateDescription.Disabled, RasterizerStateDescription.Default, PrimitiveTopology.PointList, shaderSet, new[] { particleStorageLayout, screenSizeLayout }, MainSwapchain.Framebuffer.OutputDescription); _graphicsPipeline = factory.CreateGraphicsPipeline(ref particleDrawPipelineDesc); _graphicsParticleResourceSet = factory.CreateResourceSet(new ResourceSetDescription( particleStorageLayout, _particleBuffer)); _screenSizeResourceSet = factory.CreateResourceSet(new ResourceSetDescription( screenSizeLayout, _screenSizeBuffer)); _cl = factory.CreateCommandList(); InitResources(factory); _initialized = true; }
public static VertexFragmentCompilationResult DecompileBytecode(byte[] vertexShader, byte[] fragmentShader, CrossCompileTarget target = CrossCompileTarget.GLSL) { return(SpirvCompilation.CompileVertexFragment(vertexShader, fragmentShader, target)); }