private byte[] GenerateValidUnusedShaderBytes(ShaderStages stage) { switch (stage) { case ShaderStages.Vertex: var vertexCode = @" #version 450 layout(location = 0) in vec2 Position; layout(location = 1) in vec4 Color; layout(location = 0) out vec4 fsin_Color; void main() { gl_Position = vec4(Position, 0, 1); fsin_Color = Color; }"; return(Encoding.UTF8.GetBytes(vertexCode)); case ShaderStages.Fragment: var fragmentCode = @" #version 450 layout(location = 0) in vec4 fsin_Color; layout(location = 0) out vec4 fsout_Color; void main() { fsout_Color = fsin_Color; }"; return(Encoding.UTF8.GetBytes(fragmentCode)); } return(null); }
public static IUniform <T> Create(string name, BufferUsage bufferUsage, ShaderStages shaderStages, ResourceLayoutElementOptions options = ResourceLayoutElementOptions.None) { return(new Uniform <T>(name, bufferUsage, shaderStages, options)); }
public ResourceBindingInfo(uint slot, ShaderStages stages, ResourceKind kind, bool dynamicBuffer) { Slot = slot; Stages = stages; Kind = kind; DynamicBuffer = dynamicBuffer; }
public ShaderResourceDescription(string name, ShaderResourceType type, int dataSizeInBytes, ShaderStages stages = ShaderStages.All) { Name = name; Type = type; DataSizeInBytes = dataSizeInBytes; Stages = stages; }
internal static unsafe SpirvCompilationResult CompileGlslToSpirv( uint sourceLength, byte *sourceTextPtr, string fileName, ShaderStages stage, bool debug, uint macroCount, NativeMacroDefinition *macros) { GlslCompileInfo info; info.Kind = GetShadercKind(stage); info.SourceText = new InteropArray(sourceLength, sourceTextPtr); info.Debug = debug; info.Macros = new InteropArray(macroCount, macros); if (string.IsNullOrEmpty(fileName)) { fileName = "<veldrid-spirv-input>"; } int fileNameAsciiCount = Encoding.ASCII.GetByteCount(fileName); byte *fileNameAsciiPtr = stackalloc byte[fileNameAsciiCount]; if (fileNameAsciiCount > 0) { fixed(char *fileNameTextPtr = fileName) { Encoding.ASCII.GetBytes(fileNameTextPtr, fileName.Length, fileNameAsciiPtr, fileNameAsciiCount); } } info.FileName = new InteropArray((uint)fileNameAsciiCount, fileNameAsciiPtr); CompilationResult *result = null; try { result = VeldridSpirvNative.CompileGlslToSpirv(&info); if (!result->Succeeded) { throw new SpirvCompilationException( "Compilation failed: " + Util.GetString((byte *)result->GetData(0), result->GetLength(0))); } uint length = result->GetLength(0); byte[] spirvBytes = new byte[(int)length]; fixed(byte *spirvBytesPtr = &spirvBytes[0]) { Buffer.MemoryCopy(result->GetData(0), spirvBytesPtr, length, length); } return(new SpirvCompilationResult(spirvBytes)); } finally { if (result != null) { VeldridSpirvNative.FreeResult(result); } } }
public void SetGLSL(string sourceText, ShaderStages stage, bool debug = true) { var bytes = Veldrid.SPIRV.SpirvCompilation.CompileGlslToSpirv(sourceText, "shader.spv", stage, new GlslCompileOptions(debug)); Script.Script = ShaderScriptConverter.Convert(new ShaderReflection(Shader.Parse(bytes.SpirvBytes))); }
private byte[] LoadEmbeddedShaderCode(ResourceFactory factory, string name, ShaderStages stage) { switch (factory.BackendType) { case GraphicsBackend.Direct3D11: { string resourceName = name + ".hlsl.bytes"; return(GetEmbeddedResourceBytes(resourceName)); } case GraphicsBackend.OpenGL: { string resourceName = name + ".glsl"; return(GetEmbeddedResourceBytes(resourceName)); } case GraphicsBackend.Vulkan: { string resourceName = name + ".spv"; return(GetEmbeddedResourceBytes(resourceName)); } case GraphicsBackend.Metal: { string resourceName = name + ".metallib"; return(GetEmbeddedResourceBytes(resourceName)); } default: throw new NotImplementedException(); } }
public Shader LoadShader(string name, AssetSourceEnum assetTypes, ShaderStages stage, bool useSpirvCompile = false) { //Input path should be '/' folder delimited. It is changed to '.' delimited for embedded resources var shaderFileInfo = GetShaderFileInfo(name, _systemComponents.Device, useSpirvCompile); var shaderBytes = new byte[] { }; switch (assetTypes) { case AssetSourceEnum.File: shaderBytes = TryLoadShaderBytesFromFile(shaderFileInfo); break; case AssetSourceEnum.Embedded: shaderFileInfo.Directory = shaderFileInfo.Directory.Replace('/', '.'); shaderBytes = TryLoadShaderBytesFromEmbeddedResource(shaderFileInfo); break; } if (shaderBytes.Length == 0) { _frameworkMessenger.Report(string.Concat("Unable to load shader file: ", shaderFileInfo.Directory, "| ", shaderFileInfo.Name, " | ", shaderFileInfo.Extension, ", of type --> ", assetTypes.ToString())); return(null); } return(useSpirvCompile ? _systemComponents.Factory.CreateShaderCompileFromSpirv(new ShaderDescription(stage, shaderBytes, shaderFileInfo.EntryPointMethod, true)): _systemComponents.Factory.CreateShader(new ShaderDescription(stage, shaderBytes, shaderFileInfo.EntryPointMethod, true))); }
public static string GetPath(string setName, ShaderStages stage) { return(Path.Combine( AppContext.BaseDirectory, "Shaders", $"{setName}.{stage.ToString().ToLowerInvariant().Substring(0, 4)}")); }
public static Shader LoadShader(ResourceFactory factory, string setName, ShaderStages stage, string entryPoint) { Shader shader = factory.CreateShader(new ShaderDescription(stage, LoadBytecode(factory, setName, stage), entryPoint)); shader.Name = $"{setName}-{stage.ToString()}"; return(shader); }
private static byte[] LoadBytes(string name, ShaderStages stage) { string extension = string.Empty; switch (stage) { case ShaderStages.Vertex: extension = ".vert.spv"; break; case ShaderStages.Fragment: extension = ".frag.spv"; break; case ShaderStages.Compute: extension = ".comp.spv"; break; default: throw new VxException("Invalid stage: " + stage); } string fullPath = Path.Combine(AppContext.BaseDirectory, "Shaders", name + extension); return(File.ReadAllBytes(fullPath)); }
/// <summary> /// Constructs a new ShaderDescription. /// </summary> /// <param name="stage">The shader stage to create.</param> /// <param name="shaderBytes">An array containing the raw shader bytes.</param> /// <param name="entryPoint">The name of the entry point function in the shader module to be used in this stage.</param> public ShaderDescription(ShaderStages stage, byte[] shaderBytes, string entryPoint) { Stage = stage; ShaderBytes = shaderBytes; EntryPoint = entryPoint; Debug = false; }
/// <summary> /// Compiles the given GLSL source code into SPIR-V. /// </summary> /// <param name="sourceText">The shader source code.</param> /// <param name="fileName">A descriptive name for the shader. May be null.</param> /// <param name="stage">The <see cref="ShaderStages"/> which the shader is used in.</param> /// <param name="options">Parameters for the GLSL compiler.</param> /// <returns>A <see cref="SpirvCompilationResult"/> containing the compiled SPIR-V bytecode.</returns> public static unsafe SpirvCompilationResult CompileGlslToSpirv( string sourceText, string fileName, ShaderStages stage, GlslCompileOptions options) { int sourceAsciiCount = Encoding.ASCII.GetByteCount(sourceText); byte *sourceAsciiPtr = stackalloc byte[sourceAsciiCount]; fixed(char *sourceTextPtr = sourceText) { Encoding.ASCII.GetBytes(sourceTextPtr, sourceText.Length, sourceAsciiPtr, sourceAsciiCount); } int macroCount = options.Macros.Length; NativeMacroDefinition *macros = stackalloc NativeMacroDefinition[(int)macroCount]; for (int i = 0; i < macroCount; i++) { macros[i] = new NativeMacroDefinition(options.Macros[i]); } return(CompileGlslToSpirv( (uint)sourceAsciiCount, sourceAsciiPtr, fileName, stage, options.Debug, (uint)macroCount, macros)); }
internal static ShaderType VdToGLShaderType(ShaderStages stage) { switch (stage) { case ShaderStages.Vertex: return(ShaderType.VertexShader); case ShaderStages.Geometry: return(ShaderType.GeometryShader); case ShaderStages.TessellationControl: return(ShaderType.TessControlShader); case ShaderStages.TessellationEvaluation: return(ShaderType.TessEvaluationShader); case ShaderStages.Fragment: return(ShaderType.FragmentShader); case ShaderStages.Compute: return(ShaderType.ComputeShader); default: throw Illegal.Value <ShaderStages>(); } }
internal static VkShaderStageFlags VdToVkShaderStages(ShaderStages stage) { VkShaderStageFlags ret = VkShaderStageFlags.None; if ((stage & ShaderStages.Vertex) == ShaderStages.Vertex) { ret |= VkShaderStageFlags.Vertex; } if ((stage & ShaderStages.Geometry) == ShaderStages.Geometry) { ret |= VkShaderStageFlags.Geometry; } if ((stage & ShaderStages.TessellationControl) == ShaderStages.TessellationControl) { ret |= VkShaderStageFlags.TessellationControl; } if ((stage & ShaderStages.TessellationEvaluation) == ShaderStages.TessellationEvaluation) { ret |= VkShaderStageFlags.TessellationEvaluation; } if ((stage & ShaderStages.Fragment) == ShaderStages.Fragment) { ret |= VkShaderStageFlags.Fragment; } return(ret); }
private Shader LoadShader(ShaderStages stage) { string extension = null; switch (GraphicsDevice.BackendType) { case GraphicsBackend.Direct3D11: extension = "hlsl.bytes"; break; case GraphicsBackend.Vulkan: extension = "spv"; break; case GraphicsBackend.OpenGL: extension = "glsl"; break; case GraphicsBackend.Metal: extension = "metallib"; break; default: throw new System.InvalidOperationException(); } string entryPoint = stage == ShaderStages.Vertex ? "VS" : "FS"; string path = Path.Combine(System.AppContext.BaseDirectory, "Shaders", $"{stage.ToString()}.{extension}"); byte[] shaderBytes = File.ReadAllBytes(path); return(GraphicsDevice.ResourceFactory.CreateShader(new ShaderDescription(stage, shaderBytes, entryPoint))); }
/// <summary> /// /// </summary> /// <param name="stage"></param> /// <param name="embedName"></param> /// <returns></returns> private Shader LoadEmbbedShader(ShaderStages stage, string embedName) { byte[] shaderBytes = ReadEmbeddedAssetBytes(embedName); string entryPoint = stage == ShaderStages.Vertex ? "VS" : "FS"; return(GraphicsDevice.ResourceFactory.CreateShader(new ShaderDescription(stage, shaderBytes, entryPoint))); }
/// <summary> /// Constructs a new ResourceLayoutElementDescription. /// </summary> /// <param name="name">The name of the element.</param> /// <param name="kind">The kind of resource.</param> /// <param name="stages">The <see cref="ShaderStages"/> in which this element is used.</param> public ResourceLayoutElementDescription(string name, ResourceKind kind, ShaderStages stages) { Name = name; Kind = kind; Stages = stages; Options = ResourceLayoutElementOptions.None; }
private void BindStorageBufferView(D3D11Buffer storageBufferRO, int slot, ShaderStages stages) { _context.ComputeShader.SetUnorderedAccessView(0, null); ShaderResourceView srv = storageBufferRO.ShaderResourceView; if ((stages & ShaderStages.Vertex) == ShaderStages.Vertex) { _context.VertexShader.SetShaderResource(slot, srv); } if ((stages & ShaderStages.Geometry) == ShaderStages.Geometry) { _context.GeometryShader.SetShaderResource(slot, srv); } if ((stages & ShaderStages.TessellationControl) == ShaderStages.TessellationControl) { _context.HullShader.SetShaderResource(slot, srv); } if ((stages & ShaderStages.TessellationEvaluation) == ShaderStages.TessellationEvaluation) { _context.DomainShader.SetShaderResource(slot, srv); } if ((stages & ShaderStages.Fragment) == ShaderStages.Fragment) { _context.PixelShader.SetShaderResource(slot, srv); } if ((stages & ShaderStages.Compute) == ShaderStages.Compute) { _context.ComputeShader.SetShaderResource(slot, srv); } }
/// <summary> /// Constructs a new ShaderDescription. /// </summary> /// <param name="stage">The shader stage to create.</param> /// <param name="shaderBytes">An array containing the raw shader bytes.</param> /// <param name="entryPoint">The name of the entry point function in the shader module to be used in this stage.</param> /// <param name="debug">Indicates whether the shader should be debuggable. This flag only has an effect if /// <paramref name="shaderBytes"/> contains shader code that will be compiled.</param> public ShaderDescription(ShaderStages stage, byte[] shaderBytes, string entryPoint, bool debug) { Stage = stage; ShaderBytes = shaderBytes; EntryPoint = entryPoint; Debug = debug; }
private void BindUniformBuffer(D3D11Buffer ub, int slot, ShaderStages stages) { if ((stages & ShaderStages.Vertex) == ShaderStages.Vertex) { bool bind = false; if (slot < MaxCachedUniformBuffers) { if (_vertexBoundUniformBuffers[slot] != ub) { _vertexBoundUniformBuffers[slot] = ub; bind = true; } } else { bind = true; } if (bind) { _context.VertexShader.SetConstantBuffer(slot, ub.Buffer); } } if ((stages & ShaderStages.Geometry) == ShaderStages.Geometry) { _context.GeometryShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.TessellationControl) == ShaderStages.TessellationControl) { _context.HullShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.TessellationEvaluation) == ShaderStages.TessellationEvaluation) { _context.DomainShader.SetConstantBuffer(slot, ub.Buffer); } if ((stages & ShaderStages.Fragment) == ShaderStages.Fragment) { bool bind = false; if (slot < MaxCachedUniformBuffers) { if (_fragmentBoundUniformBuffers[slot] != ub) { _fragmentBoundUniformBuffers[slot] = ub; bind = true; } } else { bind = true; } if (bind) { _context.PixelShader.SetConstantBuffer(slot, ub.Buffer); } } if ((stages & ShaderStages.Compute) == ShaderStages.Compute) { _context.ComputeShader.SetConstantBuffer(slot, ub.Buffer); } }
public ShadersBuilder AddShader(ShaderStages stage, string entryPoint, string fileName) { _shaderDescriptions.Add(new ShaderDescription(stage, Encoding.UTF8.GetBytes(_readShaderFile(fileName)), entryPoint)); _checkIfFragmentAndVertexAreCreateable(); return(this); }
/// <summary> /// Constructs a new ResourceLayoutElementDescription. /// </summary> /// <param name="name">The name of the element.</param> /// <param name="kind">The kind of resource.</param> /// <param name="stages">The <see cref="ShaderStages"/> in which this element is used.</param> /// <param name="descCount">The number of descriptors to use.</param> public ResourceLayoutElementDescription(string name, ResourceKind kind, ShaderStages stages, uint descCount) { Name = name; Kind = kind; Stages = stages; Options = ResourceLayoutElementOptions.None; DescriptorCount = descCount; }
public void EmitInternal(Variable vrbl, uint loc, ShaderStages stage) { var access = (vrbl.ReadStages.HasFlag(stage) ? "in" : "") + (vrbl.WriteStages.HasFlag(stage) ? "out" : ""); var ct = vrbl.Type.GetComponentType(); var interp = (vrbl.IsFlat || ct == ShaderType.Int || ct == ShaderType.UInt) ? "flat" : ""; _localSources[stage].AppendLine($"layout(location = {loc}) {access} {interp} {vrbl.GetGLSLDecl(stage)};"); }
public Binding(uint slot, ShaderStages smask, BindingType type, TexelFormat tfmt) { Slot = slot; StageMask = smask; Type = type; StructSize = 0; // Overridden by TexelFormat TexelFormat = tfmt; }
public Binding(uint slot, ShaderStages smask, BindingType type, uint ssize) { Slot = slot; StageMask = smask; Type = type; TexelFormat = default; // Overridden by StructSize StructSize = ssize; }
public Shader(ShaderStages stage, string entryPoint, IShaderResource glslShader, IShaderResource metalShader, IShaderResource hlslShader, IShaderResource spirvShader) { Stage = stage; EntryPoint = entryPoint; GlslShader = glslShader; MetalShader = metalShader; HlslShader = hlslShader; SpirvShader = spirvShader; }
/// <summary> /// Initializes a new instance of the <see cref="DescriptorSetLayoutBinding"/> structure. /// </summary> /// <param name="binding"> /// The binding number of this entry and corresponds to a resource of the same binding number /// in the shader stages. /// </param> /// <param name="descriptorType"> /// Specifies which type of resource descriptors are used for this binding. /// </param> /// <param name="descriptorCount"> /// The number of descriptors contained in the binding, accessed in a shader as an array. If /// <see cref="DescriptorCount"/> is zero this binding entry is reserved and the resource /// must not be accessed from any stage via this binding within any pipeline using the set layout. /// </param> /// <param name="stageFlags"> /// Specifies which pipeline shader stages can access a resource for this binding. <see /// cref="ShaderStages.All"/> is a shorthand specifying that all defined shader stages, /// including any additional stages defined by extensions, can access the resource. /// </param> /// <param name="immutableSamplers"> /// Affects initialization of samplers. If <see cref="DescriptorType"/> specifies a <see /// cref="VulkanCore.DescriptorType.Sampler"/> or <see /// cref="VulkanCore.DescriptorType.CombinedImageSampler"/> type descriptor, then <see /// cref="ImmutableSamplers"/> can be used to initialize a set of immutable samplers. /// Immutable samplers are permanently bound into the set layout; later binding a sampler /// into an immutable sampler slot in a descriptor set is not allowed. If <see /// cref="ImmutableSamplers"/> is not <c>null</c>, then it is considered to be an array of /// sampler handles that will be consumed by the set layout and used for the corresponding /// binding. If <see cref="ImmutableSamplers"/> is <c>null</c>, then the sampler slots are /// dynamic and sampler handles must be bound into descriptor sets using this layout. If <see /// cref="DescriptorType"/> is not one of these descriptor types, then <see /// cref="ImmutableSamplers"/> is ignored. /// </param> public DescriptorSetLayoutBinding(int binding, DescriptorType descriptorType, int descriptorCount, ShaderStages stageFlags = ShaderStages.All, Sampler[] immutableSamplers = null) { Binding = binding; DescriptorType = descriptorType; DescriptorCount = descriptorCount; StageFlags = stageFlags; ImmutableSamplers = immutableSamplers?.ToHandleArray(); }
public static Shader LoadShader(ResourceFactory factory, string set, ShaderStages stage, string entryPoint) { string path = Path.Combine( AppContext.BaseDirectory, "Shaders", $"{set}-{stage.ToString().ToLower()}.{GetExtension(factory.BackendType)}"); return(factory.CreateShader(new ShaderDescription(stage, File.ReadAllBytes(path), entryPoint))); }
public VkShaderBytecode(ShaderStages type, string shaderCode, string entryPoint) { if (!GlslangValidatorTool.IsAvailable()) { throw new VeldridException("glslangValidator is not available to compile GLSL to SPIR-V."); } ShaderBytes = GlslangValidatorTool.CompileBytecode(type, shaderCode, entryPoint); }