Example #1
0
        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);
        }
Example #2
0
 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;
 }
Example #5
0
        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);
                }
            }
        }
Example #6
0
        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)));
        }
Example #7
0
        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();
            }
        }
Example #8
0
        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)));
        }
Example #9
0
 public static string GetPath(string setName, ShaderStages stage)
 {
     return(Path.Combine(
                AppContext.BaseDirectory,
                "Shaders",
                $"{setName}.{stage.ToString().ToLowerInvariant().Substring(0, 4)}"));
 }
Example #10
0
        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);
        }
Example #11
0
        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;
 }
Example #13
0
        /// <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));
        }
Example #14
0
        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>();
            }
        }
Example #15
0
        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)));
        }
Example #17
0
        /// <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)));
        }
Example #18
0
 /// <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;
 }
Example #19
0
        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;
 }
Example #21
0
 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);
        }
Example #23
0
 /// <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)};");
        }
Example #25
0
 public Binding(uint slot, ShaderStages smask, BindingType type, TexelFormat tfmt)
 {
     Slot        = slot;
     StageMask   = smask;
     Type        = type;
     StructSize  = 0;                // Overridden by TexelFormat
     TexelFormat = tfmt;
 }
Example #26
0
 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;
 }
Example #28
0
 /// <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)));
        }
Example #30
0
        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);
        }