Ejemplo n.º 1
0
 public override void DestroyShaderModule(VkShaderModule shaderModule)
 {
     if (shaderModule != null)
     {
         ((SoftwareShaderModule)shaderModule).Destroy();
     }
 }
Ejemplo n.º 2
0
        private static readonly FixedUtf8String entryPoint = "main";         //The entry point of the shader

        internal ShaderPair(GraphicsDevice device, ShaderType type, VkShaderModule frag, VkShaderModule vert)
        {
            this.device     = device;
            this.shaderType = type;
            this.vkFrag     = frag;
            this.vkVert     = vert;
        }
Ejemplo n.º 3
0
        public unsafe void Init(ShaderType type, byte[] compiledShaderCode)
        {
            _type = type;
            fixed(byte *byteCodePtr = compiledShaderCode)
            {
                var shaderInfo = new VkShaderModuleCreateInfo
                {
                    sType    = VkStructureType.ShaderModuleCreateInfo,
                    codeSize = new UIntPtr((uint)compiledShaderCode.Length),
                    pCode    = (uint *)byteCodePtr
                };

                VkShaderModule shaderModule;

                if (VulkanNative.vkCreateShaderModule(
                        _device.Handle,
                        &shaderInfo,
                        null,
                        &shaderModule
                        ) != VkResult.Success)
                {
                    throw new Exception("failed to create shader module");
                }
                _handle = shaderModule;
            }
        }
Ejemplo n.º 4
0
 private void DisposeVulkanShaderModule(VkShaderModule vulkanShaderModule)
 {
     if (vulkanShaderModule != VK_NULL_HANDLE)
     {
         vkDestroyShaderModule(Device.VulkanDevice, vulkanShaderModule, pAllocator: null);
     }
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Create a new ShaderInfo object by providing directly a VkShaderModule. Note
        /// that this module will not be own by this ShaderInfo, and so will not be
        /// destroyed on Dispose.
        /// </summary>
        public ShaderInfo(VkShaderStageFlags stageFlags, VkShaderModule module, SpecializationInfo specializationInfo = null, string entryPoint = "main")
        {
            EntryPoint = new FixedUtf8String(entryPoint);

            info.stage  = stageFlags;
            info.pName  = EntryPoint;
            info.module = module;
            info.pSpecializationInfo = (specializationInfo == null) ? IntPtr.Zero : specializationInfo.InfosPtr;
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Load compiled SpirvShader.
 /// </summary>
 /// <returns>the vulkan shader module.</returns>
 /// <param name="filename">path of the spv shader.</param>
 public VkShaderModule CreateShaderModule(string filename)
 {
     using (Stream stream = Utils.GetStreamFromPath(filename)) {
         using (BinaryReader br = new BinaryReader(stream)) {
             byte[]         shaderCode   = br.ReadBytes((int)stream.Length);
             UIntPtr        shaderSize   = (UIntPtr)shaderCode.Length;
             VkShaderModule shaderModule = CreateShaderModule(shaderCode.Pin(), shaderSize);
             shaderCode.Unpin();
             return(shaderModule);
         }
     }
 }/// <summary>
Ejemplo n.º 7
0
 public ShaderProgram(
     VkShaderModule vert,
     VkShaderModule?tesc,
     VkShaderModule?tese,
     VkShaderModule?geom,
     VkShaderModule frag)
     : base(ResourceType.ShaderProgram)
 {
     Vert = vert;
     Tesc = tesc;
     Tese = tese;
     Geom = geom;
     Frag = frag;
 }
Ejemplo n.º 8
0
        private VkShaderModule createShaderModule(Type shaderCode)
        {
            VkShaderModuleCreateInfo createInfo = new VkShaderModuleCreateInfo();

            createInfo.sType = VkStructureType.VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO;
            createInfo.pCode = shaderCode;

            VkShaderModule shaderModule = null;
            VkResult       result;

            result = Vulkan.vkCreateShaderModule(device, createInfo, default(VkAllocationCallbacks), out shaderModule);
            if (result != VkResult.VK_SUCCESS)
            {
                throw Program.Throw("failed to create shader module!", result);
            }

            return(shaderModule);
        }
Ejemplo n.º 9
0
        static VkShaderModule LoadShader(VkDevice device, string path)
        {
            byte[] bytes = File.ReadAllBytes(path);

            uint length = (uint)bytes.Length;

            VkShaderModuleCreateInfo pCreateInfo = VkShaderModuleCreateInfo.New();

            pCreateInfo.codeSize = (UIntPtr)length;

            fixed(byte *ptr = bytes)
            pCreateInfo.pCode = (uint *)ptr;

            VkShaderModule shaderModule = new VkShaderModule();

            Assert(vkCreateShaderModule(device, &pCreateInfo, null, &shaderModule));

            return(shaderModule);
        }
Ejemplo n.º 10
0
            internal ShaderStageBuilder(GraphicsPipelineBuilder builder, VkShaderModule handle,
                                        VkShaderStageFlag stage, string entryPoint)
            {
                _builder = builder;
                unsafe
                {
                    _shaderInfo = new VkPipelineShaderStageCreateInfo()
                    {
                        SType  = VkStructureType.PipelineShaderStageCreateInfo,
                        PNext  = IntPtr.Zero,
                        Module = handle,
                        Flags  = 0,
                        Stage  = stage,
                        PSpecializationInfo = (VkSpecializationInfo *)0
                    };
                }

                _entryPoint = entryPoint;
            }
Ejemplo n.º 11
0
        public static VkResult vkCreateShaderModule(VkDevice device, byte[] bytecode, VkAllocationCallbacks *allocator, out VkShaderModule shaderModule)
        {
            fixed(byte *bytecodePtr = bytecode)
            {
                var createInfo = new VkShaderModuleCreateInfo
                {
                    sType    = VkStructureType.ShaderModuleCreateInfo,
                    codeSize = new VkPointerSize((uint)bytecode.Length),
                    pCode    = (uint *)bytecodePtr
                };

                return(vkCreateShaderModule(device, &createInfo, allocator, out shaderModule));
            }
        }
Ejemplo n.º 12
0
 /// <summary>
 /// Add a new shader to this pipeline configuration.
 /// </summary>
 public void AddShader(VkShaderStageFlags stageFlags, VkShaderModule module, SpecializationInfo specializationInfo = null, string entryPoint = "main")
 {
     Shaders.Add(new ShaderInfo(stageFlags, module, specializationInfo, entryPoint));
 }
Ejemplo n.º 13
0
        public void CreateGraphicsPipeline(string[] fileShaders, Framebuffer framebuffer)
        {
            VkShaderModule vertexShader   = NativeDevice.LoadSPIR_V_Shader(fileShaders[0], ShaderCompiler.ShaderCompiler.Stage.vertex_shader);
            VkShaderModule fragmentShader = NativeDevice.LoadSPIR_V_Shader(fileShaders[1], ShaderCompiler.ShaderCompiler.Stage.fragment_shader);

            VkPipelineShaderStageCreateInfo vertCreateInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.PipelineShaderStageCreateInfo,
                pNext  = null,
                stage  = VkShaderStageFlags.Vertex,
                module = vertexShader,
                pName  = Interop.String.ToPointer("main"),
            };


            VkPipelineShaderStageCreateInfo fragCreateInfo = new VkPipelineShaderStageCreateInfo
            {
                sType  = VkStructureType.PipelineShaderStageCreateInfo,
                pNext  = null,
                flags  = 0,
                stage  = VkShaderStageFlags.Fragment,
                module = fragmentShader,
                pName  = Interop.String.ToPointer("main"),
            };


            VkPipelineShaderStageCreateInfo *shaderStageCreateInfos = stackalloc VkPipelineShaderStageCreateInfo[2];

            shaderStageCreateInfos[0] = vertCreateInfo;
            shaderStageCreateInfos[1] = fragCreateInfo;

            VkPipelineVertexInputStateCreateInfo vertexInputStateCI = VkPipelineVertexInputStateCreateInfo.New();

            //var vertexBindingDesc = Vertex.GetBindingDescription();
            vertexInputStateCI.vertexBindingDescriptionCount = 0;
            //vertexInputStateCI.pVertexBindingDescriptions = Interop.Struct.AllocToPointer(ref vertexBindingDesc);


            vertexInputStateCI.vertexAttributeDescriptionCount = 0;
            //vertexInputStateCI.pVertexAttributeDescriptions = Interop.Struct.AllocToPointer(Vertex.GetAttributeDescriptions());
            //vertexInputStateCI.pVertexAttributeDescriptions = Interop.Struct.AllocToPointer(Vertex.GetAttributeDescriptions().AsSpan());

            VkPipelineInputAssemblyStateCreateInfo inputAssemblyCI = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssemblyCI.primitiveRestartEnable = false;
            inputAssemblyCI.topology = VkPrimitiveTopology.TriangleList;



            VkPipelineRasterizationStateCreateInfo rasterizerStateCI = VkPipelineRasterizationStateCreateInfo.New();

            rasterizerStateCI.cullMode    = VkCullModeFlags.None;
            rasterizerStateCI.polygonMode = VkPolygonMode.Fill;
            rasterizerStateCI.lineWidth   = 2.5f;
            rasterizerStateCI.frontFace   = VkFrontFace.CounterClockwise;

            VkPipelineMultisampleStateCreateInfo multisampleStateCI = VkPipelineMultisampleStateCreateInfo.New();

            multisampleStateCI.rasterizationSamples = VkSampleCountFlags.Count1;
            multisampleStateCI.minSampleShading     = 1f;

            VkPipelineColorBlendAttachmentState colorBlendAttachementState = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachementState.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;
            colorBlendAttachementState.blendEnable    = false;

            VkPipelineColorBlendStateCreateInfo colorBlendStateCI = VkPipelineColorBlendStateCreateInfo.New();

            colorBlendStateCI.attachmentCount = 1;
            colorBlendStateCI.pAttachments    = &colorBlendAttachementState;

            //VkDescriptorSetLayout dsl = _descriptoSetLayout;
            VkPipelineLayoutCreateInfo pipelineLayoutCI = VkPipelineLayoutCreateInfo.New();

            pipelineLayoutCI.setLayoutCount = 0;
            //pipelineLayoutCI.pSetLayouts = &dsl;
            vkCreatePipelineLayout(NativeDevice.Device, ref pipelineLayoutCI, null, out pipelineLayout);

            VkGraphicsPipelineCreateInfo graphicsPipelineCI = VkGraphicsPipelineCreateInfo.New();

            graphicsPipelineCI.stageCount = 2;
            graphicsPipelineCI.pStages    = shaderStageCreateInfos;

            graphicsPipelineCI.pVertexInputState   = &vertexInputStateCI;
            graphicsPipelineCI.pInputAssemblyState = &inputAssemblyCI;
            graphicsPipelineCI.pRasterizationState = &rasterizerStateCI;
            graphicsPipelineCI.pMultisampleState   = &multisampleStateCI;
            graphicsPipelineCI.pColorBlendState    = &colorBlendStateCI;
            graphicsPipelineCI.layout     = pipelineLayout;
            graphicsPipelineCI.renderPass = framebuffer.NativeRenderPass;
            graphicsPipelineCI.subpass    = 0;

            vkCreateGraphicsPipelines(NativeDevice.Device, VkPipelineCache.Null, 1, ref graphicsPipelineCI, null, out graphicsPipeline);
        }
Ejemplo n.º 14
0
        public static VkResult vkCreateShaderModule(VkDevice device, VkShaderModuleCreateInfo createInfo, VkAllocationCallbacks pAllocator, out VkShaderModule shaderModule)
        {
            VkPreconditions.CheckNull(device, nameof(device));

            return(GetDevice(device).CreateShaderModule(createInfo, out shaderModule));
        }
Ejemplo n.º 15
0
 public static extern void DestroyShaderModule(
     VkDevice device,
     VkShaderModule shaderModule,
     IntPtr pAllocator
     );
Ejemplo n.º 16
0
 public override VkResult CreateShaderModule(VkShaderModuleCreateInfo createInfo, out VkShaderModule shaderModule)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 17
0
 /// <summary>
 /// Dispose ShaderInfo at index 'shaderIndex' in the Shaders list, and replace it with a new one.
 /// </summary>
 public void ReplaceShader(int shaderIndex, VkShaderStageFlags stageFlags, VkShaderModule module, SpecializationInfo specializationInfo = null, string entryPoint = "main")
 {
     Shaders[shaderIndex].Dispose();
     Shaders[shaderIndex] = new ShaderInfo(stageFlags, module, specializationInfo, entryPoint);
 }
Ejemplo n.º 18
0
 public void DestroyShaderModule(VkShaderModule module)
 {
     vkDestroyShaderModule(VkDev, module, IntPtr.Zero);
     module = 0;
 }
Ejemplo n.º 19
0
        public FGraphicsPipeline(VkDevice device, VkPhysicalDevice physicalDevice, VkPipelineCache pipelineCache, VkRenderPass renderPass,
                                 string shaderPath, uint swapchainImageCount, FTexture textureArray)
        {
            this.device = device;
            this.swapchainImageCount = swapchainImageCount;
            this.renderPass          = renderPass;

            desclayout     = CreateDescriptorLayout(device, 1);
            descriptorPool = CreateDescriptorPool(device, swapchainImageCount, 7);
            descriptorSets = AllocateDescriptorSets(device, desclayout, descriptorPool,
                                                    swapchainImageCount);

            sampler = CreateSampler(device, textureArray.MipLevels);
            for (int i = 0; i < swapchainImageCount; i++)
            {
                VkDescriptorImageInfo imageInfo = new VkDescriptorImageInfo();
                imageInfo.imageLayout = VkImageLayout.ShaderReadOnlyOptimal;
                imageInfo.imageView   = textureArray.imageView;
                imageInfo.sampler     = sampler;

                VkWriteDescriptorSet[] writes = new VkWriteDescriptorSet[1];
                writes[0].dstSet          = descriptorSets[i];
                writes[0].dstBinding      = 0;
                writes[0].dstArrayElement = 0;
                writes[0].descriptorType  = VkDescriptorType.CombinedImageSampler;
                writes[0].descriptorCount = 1;
                writes[0].pImageInfo      = &imageInfo;

                fixed(VkWriteDescriptorSet *ptr = writes)
                vkUpdateDescriptorSets(device, (uint)writes.Length, ptr, 0, null);
            }

            uniformdata = CreateUniformBuffer(device, physicalDevice, 1);

            VkShaderModule vs = LoadShader(device, $"{shaderPath}.vert.spv");
            VkShaderModule fs = LoadShader(device, $"{shaderPath}.frag.spv");


            VkGraphicsPipelineCreateInfo pCreateInfo = VkGraphicsPipelineCreateInfo.New();

            pCreateInfo.flags = VkPipelineCreateFlags.DisableOptimization;

            VkPipelineShaderStageCreateInfo[] shaderStages = new VkPipelineShaderStageCreateInfo[2];
            shaderStages[0]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[0].stage  = VkShaderStageFlags.Vertex;
            shaderStages[0].module = vs;

            byte[] vsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(vsFuncName[0]))
            shaderStages[0].pName = ptr;

            shaderStages[1]        = VkPipelineShaderStageCreateInfo.New();
            shaderStages[1].stage  = VkShaderStageFlags.Fragment;
            shaderStages[1].module = fs;
            byte[] fsFuncName = Encoding.UTF8.GetBytes("main" + char.MinValue);

            fixed(byte *ptr = &(fsFuncName[0]))
            shaderStages[1].pName = ptr;

            fixed(VkPipelineShaderStageCreateInfo *ptr = shaderStages)
            pCreateInfo.pStages = ptr;

            pCreateInfo.stageCount = 2;

            VkVertexInputBindingDescription[] bindings = new VkVertexInputBindingDescription[4];
            bindings[0]           = new VkVertexInputBindingDescription();
            bindings[0].binding   = 0;
            bindings[0].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[0].inputRate = VkVertexInputRate.Vertex;

            bindings[1]           = new VkVertexInputBindingDescription();
            bindings[1].binding   = 1;
            bindings[1].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[1].inputRate = VkVertexInputRate.Vertex;

            bindings[2]           = new VkVertexInputBindingDescription();
            bindings[2].binding   = 2;
            bindings[2].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[2].inputRate = VkVertexInputRate.Vertex;

            bindings[3]           = new VkVertexInputBindingDescription();
            bindings[3].binding   = 3;
            bindings[3].stride    = (uint)sizeof(VoxelRenderer.VoxelVertex);
            bindings[3].inputRate = VkVertexInputRate.Vertex;

            VkVertexInputAttributeDescription[] attribs = new VkVertexInputAttributeDescription[4];
            attribs[0].binding  = 0;
            attribs[0].location = 0;
            attribs[0].format   = VkFormat.R32g32b32Sfloat;
            attribs[0].offset   = 0;

            attribs[1].binding  = 1;
            attribs[1].location = 1;
            attribs[1].format   = VkFormat.R32g32b32Sfloat;
            attribs[1].offset   = 0;

            attribs[2].binding  = 2;
            attribs[2].location = 2;
            attribs[2].format   = VkFormat.R32g32b32Sfloat;
            attribs[2].offset   = 0;

            attribs[3].binding  = 3;
            attribs[3].location = 3;
            attribs[3].format   = VkFormat.R32Uint;
            attribs[3].offset   = 0;

            VkPipelineVertexInputStateCreateInfo vertexInput = VkPipelineVertexInputStateCreateInfo.New();

            fixed(VkVertexInputBindingDescription *ptr = bindings)
            vertexInput.pVertexBindingDescriptions = ptr;

            vertexInput.vertexBindingDescriptionCount = (uint)bindings.Length;

            fixed(VkVertexInputAttributeDescription *ptr = attribs)
            vertexInput.pVertexAttributeDescriptions = ptr;

            vertexInput.vertexAttributeDescriptionCount = (uint)attribs.Length;
            pCreateInfo.pVertexInputState = &vertexInput;

            VkPipelineInputAssemblyStateCreateInfo inputAssembly = VkPipelineInputAssemblyStateCreateInfo.New();

            inputAssembly.topology          = VkPrimitiveTopology.TriangleList;
            pCreateInfo.pInputAssemblyState = &inputAssembly;

            VkPipelineViewportStateCreateInfo viewportState = VkPipelineViewportStateCreateInfo.New();

            viewportState.viewportCount = 1;
            viewportState.scissorCount  = 1;
            pCreateInfo.pViewportState  = &viewportState;

            VkPipelineRasterizationStateCreateInfo rasterizationState = VkPipelineRasterizationStateCreateInfo.New();

            rasterizationState.lineWidth    = 1;
            rasterizationState.frontFace    = VkFrontFace.Clockwise;
            rasterizationState.cullMode     = VkCullModeFlags.Back;
            rasterizationState.polygonMode  = VkPolygonMode.Fill;//TODO add line debug render
            pCreateInfo.pRasterizationState = &rasterizationState;

            VkPipelineMultisampleStateCreateInfo multisampleState = VkPipelineMultisampleStateCreateInfo.New();

            multisampleState.rasterizationSamples = VkSampleCountFlags.Count1;
            pCreateInfo.pMultisampleState         = &multisampleState;

            VkPipelineDepthStencilStateCreateInfo depthState = VkPipelineDepthStencilStateCreateInfo.New();

            depthState.depthTestEnable     = VkBool32.True;
            depthState.depthWriteEnable    = VkBool32.True;
            depthState.depthCompareOp      = VkCompareOp.Less;
            pCreateInfo.pDepthStencilState = &depthState;

            VkPipelineColorBlendAttachmentState colourAttachment = new VkPipelineColorBlendAttachmentState();

            colourAttachment.colorWriteMask = VkColorComponentFlags.R | VkColorComponentFlags.G | VkColorComponentFlags.B | VkColorComponentFlags.A;

            VkPipelineColorBlendStateCreateInfo colourState = VkPipelineColorBlendStateCreateInfo.New();

            colourState.pAttachments     = &colourAttachment;
            colourState.attachmentCount  = 1;
            pCreateInfo.pColorBlendState = &colourState;

            VkDynamicState[] dynamicStates = new VkDynamicState[2];
            dynamicStates[0] = VkDynamicState.Viewport;
            dynamicStates[1] = VkDynamicState.Scissor;

            VkPipelineDynamicStateCreateInfo dynamicState = VkPipelineDynamicStateCreateInfo.New();

            dynamicState.dynamicStateCount = (uint)dynamicStates.Length;

            fixed(VkDynamicState *ptr = &(dynamicStates[0]))
            dynamicState.pDynamicStates = ptr;

            pCreateInfo.pDynamicState = &dynamicState;

            this.pipelineLayout    = CreatePipelineLayout(device, desclayout);
            pCreateInfo.layout     = this.pipelineLayout;
            pCreateInfo.renderPass = renderPass;
            pCreateInfo.subpass    = 0;


            VkPipeline pipeline = VkPipeline.Null;

            Assert(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pCreateInfo, null, &pipeline));
            this.pipeline = pipeline;
        }
Ejemplo n.º 20
0
 public override VkResult CreateShaderModule(VkShaderModuleCreateInfo createInfo, out VkShaderModule shaderModule)
 {
     shaderModule = new SoftwareShaderModule(this, createInfo);
     return(VkResult.VK_SUCCESS);
 }
Ejemplo n.º 21
0
Archivo: VSL.cs Proyecto: LibVega/Vega
        // Parse a compiled VSL shader and return the info and modules
        public static void LoadStream(string path, Stream stream,
                                      out ShaderLayout info,
                                      out VkShaderModule vertMod, out VkShaderModule fragMod)
        {
            // Open the file and check the header
            using var file = new BinaryReader(stream);
            Span <byte> header = stackalloc byte[4];

            file.Read(header);
            if ((header[0] != 'V') || (header[1] != 'B') || (header[2] != 'C'))
            {
                throw new InvalidShaderException(path, "Invalid magic number");
            }
            if (header[3] != 1)
            {
                throw new InvalidShaderException(path, "Invalid shader file version");
            }

            // Read rest of header
            file.Read(header.Slice(0, 1));
            if (header[0] != 1)
            {
                throw new InvalidShaderException(path, "Invalid shader type, only graphics shaders supported");
            }
            Span <ushort> bcLengths = stackalloc ushort[5];

            file.Read(MemoryMarshal.AsBytes(bcLengths));
            Span <ushort> tableSizes = stackalloc ushort[5];

            file.Read(MemoryMarshal.AsBytes(tableSizes));

            // Validate header values
            if (bcLengths[0] == 0)
            {
                throw new InvalidShaderException(path, "Shader has no vertex stage");
            }
            if ((bcLengths[1] != 0) || (bcLengths[2] != 0) || (bcLengths[3] != 0))
            {
                throw new InvalidShaderException(path, "Shader has unsupported stages");
            }
            if (bcLengths[4] == 0)
            {
                throw new InvalidShaderException(path, "Shader has no fragment stage");
            }
            if ((tableSizes[0] != BindingTable.DEFAULT_SIZE_SAMPLER) || (tableSizes[1] != BindingTable.DEFAULT_SIZE_IMAGE) ||
                (tableSizes[2] != BindingTable.DEFAULT_SIZE_BUFFER) || (tableSizes[3] != BindingTable.DEFAULT_SIZE_ROTEXELS) ||
                (tableSizes[4] != BindingTable.DEFAULT_SIZE_RWTEXELS))
            {
                throw new InvalidShaderException(path, "Invalid binding table sizes");
            }

            // Read the vertex inputs
            var inputCount = file.ReadUInt32();
            Span <InterfaceVariable> inputs = stackalloc InterfaceVariable[(int)inputCount];

            file.Read(MemoryMarshal.AsBytes(inputs));
            ProcessVertexInputs(path, inputs, out var reflInputs);

            // Read the fragment outputs
            var outputCount = file.ReadUInt32();
            Span <InterfaceVariable> outputs = stackalloc InterfaceVariable[(int)outputCount];

            file.Read(MemoryMarshal.AsBytes(outputs));
            ProcessFragmentOutputs(path, outputs, out var reflOutputs);

            // Read the bindings
            var bindingCount = file.ReadUInt32();
            Span <BindingVariable> bindings = stackalloc BindingVariable[(int)bindingCount];

            file.Read(MemoryMarshal.AsBytes(bindings));
            ProcessBindings(path, bindings, out var reflBindings);

            // Read the uniform info
            var uniformSize = file.ReadUInt16();

            ShaderLayout.UniformMember[]? reflUniformMembers = null;
            ShaderStages uniformStages = ShaderStages.None;

            if (uniformSize > 0)
            {
                uniformStages = (ShaderStages)file.ReadUInt16();
                var uniformMemberCount      = file.ReadUInt32();
                Span <StructMember> members = stackalloc StructMember[(int)uniformMemberCount];
                var         memberNames     = new string[uniformMemberCount];
                Span <byte> nameBytes       = stackalloc byte[64];
                for (uint i = 0; i < uniformMemberCount; ++i)
                {
                    uint nameLength = file.ReadByte();
                    var  thisName   = nameBytes.Slice(0, (int)nameLength);
                    file.Read(thisName);
                    file.Read(MemoryMarshal.AsBytes(members.Slice((int)i, 1)));
                    memberNames[i] = Encoding.ASCII.GetString(thisName);
                }
                ProcessUniformMembers(path, members, memberNames, out reflUniformMembers);
            }

            // Read the subpass inputs
            var spiCount            = file.ReadUInt32();
            Span <SubpassInput> spi = stackalloc SubpassInput[(int)spiCount];

            if (spiCount > 0)
            {
                file.Read(MemoryMarshal.AsBytes(spi));
            }
            ProcessSubpassInputs(path, spi, out var reflSpi);

            // Read the bytecodes
            var vertBC = new uint[bcLengths[0]];
            var fragBC = new uint[bcLengths[4]];

            file.Read(MemoryMarshal.AsBytes(new Span <uint>(vertBC)));
            file.Read(MemoryMarshal.AsBytes(new Span <uint>(fragBC)));

            // Last validation
            if (file.BaseStream.Position != file.BaseStream.Length)
            {
                throw new InvalidShaderException(path, "File not fully consumed by parser");
            }

            // Create shader modules
            info = new(
                ShaderStages.Vertex | ShaderStages.Fragment,
                reflInputs,
                reflOutputs,
                reflBindings,
                uniformSize, uniformStages, reflUniformMembers ?? Array.Empty <ShaderLayout.UniformMember>(),
                reflSpi
                );
            CreateShaderModules(path, Core.Instance !.Graphics.VkDevice,
                                vertBC, fragBC,
                                out vertMod, out fragMod
                                );
        }
Ejemplo n.º 22
0
        void CreateGraphicsPipeline()
        {
            VkShaderModule vert = CreateShaderModule(File.ReadAllBytes("vert.spv"));
            VkShaderModule frag = CreateShaderModule(File.ReadAllBytes("frag.spv"));

            InteropString entry = new InteropString("main");

            var vertInfo = new VkPipelineShaderStageCreateInfo();

            vertInfo.sType  = CSGL.Vulkan.VkStructureType.PipelineShaderStageCreateInfo;
            vertInfo.stage  = CSGL.Vulkan.VkShaderStageFlags.VertexBit;
            vertInfo.module = vert;
            vertInfo.pName  = entry.Address;

            var fragInfo = new VkPipelineShaderStageCreateInfo();

            fragInfo.sType  = CSGL.Vulkan.VkStructureType.PipelineShaderStageCreateInfo;
            fragInfo.stage  = CSGL.Vulkan.VkShaderStageFlags.FragmentBit;
            fragInfo.module = frag;
            fragInfo.pName  = entry.Address;

            var shaderStages = new NativeArray <VkPipelineShaderStageCreateInfo>(2);

            shaderStages[0] = vertInfo;
            shaderStages[1] = fragInfo;

            var vertexInputInfo = new VkPipelineVertexInputStateCreateInfo();

            vertexInputInfo.sType = CSGL.Vulkan.VkStructureType.PipelineVertexInputStateCreateInfo;

            var vertexInputNative = new Native <VkPipelineVertexInputStateCreateInfo>(vertexInputInfo);

            var inputAssembly = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssembly.sType    = CSGL.Vulkan.VkStructureType.PipelineInputAssemblyStateCreateInfo;
            inputAssembly.topology = CSGL.Vulkan.VkPrimitiveTopology.TriangleList;

            var inputAssemblyNative = new Native <VkPipelineInputAssemblyStateCreateInfo>(inputAssembly);

            var viewport = new VkViewport();

            viewport.width    = swapchainExtent.width;
            viewport.height   = swapchainExtent.height;
            viewport.minDepth = 0f;
            viewport.maxDepth = 1f;

            var viewportNative = new Native <VkViewport>(viewport);

            var scissor = new VkRect2D();

            scissor.extent = swapchainExtent;

            var scissorNative = new Native <VkRect2D>(scissor);

            var viewportState = new VkPipelineViewportStateCreateInfo();

            viewportState.sType         = CSGL.Vulkan.VkStructureType.PipelineViewportStateCreateInfo;
            viewportState.viewportCount = 1;
            viewportState.pViewports    = viewportNative.Address;
            viewportState.scissorCount  = 1;
            viewportState.pScissors     = scissorNative.Address;

            var viewportStateNative = new Native <VkPipelineViewportStateCreateInfo>(viewportState);

            var rasterizer = new VkPipelineRasterizationStateCreateInfo();

            rasterizer.sType       = CSGL.Vulkan.VkStructureType.PipelineRasterizationStateCreateInfo;
            rasterizer.polygonMode = CSGL.Vulkan.VkPolygonMode.Fill;
            rasterizer.lineWidth   = 1f;
            rasterizer.cullMode    = CSGL.Vulkan.VkCullModeFlags.BackBit;
            rasterizer.frontFace   = CSGL.Vulkan.VkFrontFace.Clockwise;

            var rasterizerNative = new Native <VkPipelineRasterizationStateCreateInfo>(rasterizer);

            var multisampling = new VkPipelineMultisampleStateCreateInfo();

            multisampling.sType = CSGL.Vulkan.VkStructureType.PipelineMultisampleStateCreateInfo;
            multisampling.rasterizationSamples = CSGL.Vulkan.VkSampleCountFlags._1_Bit;
            multisampling.minSampleShading     = 1f;

            var multisamplingNative = new Native <VkPipelineMultisampleStateCreateInfo>(multisampling);

            var colorBlendAttachment = new VkPipelineColorBlendAttachmentState();

            colorBlendAttachment.colorWriteMask = CSGL.Vulkan.VkColorComponentFlags.RBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.GBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.BBit
                                                  | CSGL.Vulkan.VkColorComponentFlags.ABit;
            colorBlendAttachment.srcColorBlendFactor = CSGL.Vulkan.VkBlendFactor.One;
            colorBlendAttachment.dstColorBlendFactor = CSGL.Vulkan.VkBlendFactor.Zero;
            colorBlendAttachment.colorBlendOp        = CSGL.Vulkan.VkBlendOp.Add;
            colorBlendAttachment.srcAlphaBlendFactor = CSGL.Vulkan.VkBlendFactor.One;
            colorBlendAttachment.dstAlphaBlendFactor = CSGL.Vulkan.VkBlendFactor.Zero;
            colorBlendAttachment.alphaBlendOp        = CSGL.Vulkan.VkBlendOp.Add;

            var colorBlendAttachmentNative = new Native <VkPipelineColorBlendAttachmentState>(colorBlendAttachment);

            var colorBlending = new VkPipelineColorBlendStateCreateInfo();

            colorBlending.sType           = CSGL.Vulkan.VkStructureType.PipelineColorBlendStateCreateInfo;
            colorBlending.logicOp         = CSGL.Vulkan.VkLogicOp.Copy;
            colorBlending.attachmentCount = 1;
            colorBlending.pAttachments    = colorBlendAttachmentNative.Address;

            var colorBlendingNative = new Native <VkPipelineColorBlendStateCreateInfo>(colorBlending);

            var pipelineLayoutInfo = new VkPipelineLayoutCreateInfo();

            pipelineLayoutInfo.sType = CSGL.Vulkan.VkStructureType.PipelineLayoutCreateInfo;

            if (pipelineLayout != VkPipelineLayout.Null)
            {
                VK.DestroyPipelineLayout(device, pipelineLayout, alloc);
            }
            var result = VK.CreatePipelineLayout(device, ref pipelineLayoutInfo, alloc, out pipelineLayout);

            var info = new VkGraphicsPipelineCreateInfo();

            info.sType               = CSGL.Vulkan.VkStructureType.GraphicsPipelineCreateInfo;
            info.stageCount          = 2;
            info.pStages             = shaderStages.Address;
            info.pVertexInputState   = vertexInputNative.Address;
            info.pInputAssemblyState = inputAssemblyNative.Address;
            info.pViewportState      = viewportStateNative.Address;
            info.pRasterizationState = rasterizerNative.Address;
            info.pMultisampleState   = multisamplingNative.Address;
            info.pColorBlendState    = colorBlendingNative.Address;
            info.layout              = pipelineLayout;
            info.renderPass          = renderPass;
            info.subpass             = 0;
            info.basePipelineHandle  = VkPipeline.Null;
            info.basePipelineIndex   = -1;

            var infoNative = new Native <VkGraphicsPipelineCreateInfo>(info);
            var temp       = new Native <VkPipeline>();

            if (pipeline != VkPipeline.Null)
            {
                VK.DestroyPipeline(device, pipeline, alloc);
            }

            result   = VK.CreateGraphicsPipelines(device, VkPipelineCache.Null, 1, infoNative.Address, alloc, temp.Address);
            pipeline = temp.Value;

            infoNative.Dispose();
            temp.Dispose();

            entry.Dispose();
            shaderStages.Dispose();
            vertexInputNative.Dispose();
            inputAssemblyNative.Dispose();
            viewportNative.Dispose();
            scissorNative.Dispose();
            viewportStateNative.Dispose();
            rasterizerNative.Dispose();
            multisamplingNative.Dispose();
            colorBlendingNative.Dispose();
            colorBlendAttachmentNative.Dispose();
            VK.DestroyShaderModule(device, vert, alloc);
            VK.DestroyShaderModule(device, frag, alloc);
        }
Ejemplo n.º 23
0
 public override void DestroyShaderModule(VkShaderModule shaderModule)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 24
0
 public abstract void DestroyShaderModule(VkShaderModule shaderModule);
Ejemplo n.º 25
0
 public static extern VkResult CreateShaderModule(
     VkDevice device,
     ref VkShaderModuleCreateInfo pCreateInfo,
     IntPtr pAllocator,
     out VkShaderModule pShaderModule
     );
Ejemplo n.º 26
0
 public abstract VkResult CreateShaderModule(VkShaderModuleCreateInfo createInfo, out VkShaderModule shaderModule);
Ejemplo n.º 27
0
        public static void vkDestroyShaderModule(VkDevice device, VkShaderModule shaderModule, VkAllocationCallbacks pAllocator)
        {
            VkPreconditions.CheckNull(device, nameof(device));

            GetDevice(device).DestroyShaderModule(shaderModule);
        }
Ejemplo n.º 28
0
        public Triangle()
        {
            InitializeComponent();
            InitializeVulkan();
            _Bitmap = new Bitmap(640, 480);

            _Framebuffer = new Framebuffer(_Device, 640, 480);

            VkPipelineLayout dummyLayout = _Device.CreatePipelineLayout(VkPipelineLayoutCreateFlag.NONE, null, null);

            _VertexShader   = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/vertexShader.spv"));
            _FramgemtShader = _Device.CreateShaderModule(VkShaderModuleCreateFlag.NONE, System.IO.File.ReadAllBytes("./Shaders/fragmentShader.spv"));


            _GraphicsPipeline = new Pipeline(_Framebuffer, dummyLayout, _VertexShader, "main", _FramgemtShader, "main");

            // Finally we will need a fence for our submission in order to wait on it
            _Fence = _Device.CreateFence(VkFenceCreateFlag.NONE);

            // VkBuffer indexBuffer = _Device.CreateBuffer(0, 3 * sizeof(Int32), VkBufferUsageFlag.VK_BUFFER_USAGE_INDEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family });
            // VkBuffer vertexBuffer = _Device.CreateBuffer(0, 3 * sizeof(float), VkBufferUsageFlag.VK_BUFFER_USAGE_VERTEX_BUFFER, VkSharingMode.VK_SHARING_MODE_CONCURRENT, new VkQueueFamilyProperties[] { _Queue.Family });


            // Now we need to create a command buffer and we will fill it with a single command:
            //   Fill the image with the color (0.1f, 0.75f, 1.0f, 1.0f) which is a Sky blue.
            VkClearValue.VkClearColorValue.Float color = new VkClearValue.VkClearColorValue.Float();
            color.float32[0] = 0.1f; color.float32[1] = 0.75f; color.float32[2] = 1.0f; color.float32[3] = 1.0f;
            VkCommandPool Pool = _Device.CreateCommandPool(VkCommandPoolCreateFlag.NONE, _Queue.Family);

            _CommandBuffer = Pool.AllocateCommandBuffer(VkCommandBufferLevel.VK_COMMAND_BUFFER_LEVEL_PRIMARY);
            _CommandBuffer.Begin(VkCommandBufferUsageFlag.NONE);
            _CommandBuffer.CmdBeginRenderPass(_Framebuffer.RenderPass,
                                              new VkRect2D(0, 0, (uint)640, (uint)480),
                                              _Framebuffer.GetFramebuffer(),
                                              new VkClearValue[] { color },
                                              VkSubpassContents.VK_SUBPASS_CONTENTS_INLINE);

            _GraphicsPipeline.BindPipeline(_CommandBuffer);
            _CommandBuffer.CmdDraw(3, 1, 0, 0);
            _CommandBuffer.CmdEndRenderPass();
            _CommandBuffer.cmdCopyImageToBuffer(_Framebuffer.FrameBufferColor,
                                                VkImageLayout.VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL,
                                                _Framebuffer._TransferBuffer,
                                                new VkBufferImageCopy[]
            {
                new VkBufferImageCopy()
                {
                    bufferImageHeight = (uint)_Framebuffer.Height,
                    bufferOffset      = 0,
                    bufferRowLength   = (uint)_Framebuffer.Width,
                    imageExtent       = new VkExtent3D()
                    {
                        depth = 1, width = (uint)_Framebuffer.Width, height = (uint)_Framebuffer.Height
                    },
                    imageSubresource = new VkImageSubresourceLayers()
                    {
                        aspectMask = VkImageAspectFlag.VK_IMAGE_ASPECT_COLOR_BIT, baseArrayLayer = 0, layerCount = 1, mipLevel = 0
                    }
                }
            });
            _CommandBuffer.End();
        }
Ejemplo n.º 29
0
        private void CreateGraphicsPipeline()
        {
            byte[] vertShaderCode = File.ReadAllBytes("Shaders/vert.spv");
            byte[] fragShaderCode = File.ReadAllBytes("Shaders/frag.spv");

            VkShaderModule vertShaderModule = this.CreateShaderModule(vertShaderCode);
            VkShaderModule fragShaderModule = this.CreateShaderModule(fragShaderCode);

            VkPipelineShaderStageCreateInfo vertShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlags.VK_SHADER_STAGE_VERTEX_BIT,
                module = vertShaderModule,
                pName  = "main".ToPointer(),
            };

            VkPipelineShaderStageCreateInfo fragShaderStageInfo = new VkPipelineShaderStageCreateInfo()
            {
                sType  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO,
                stage  = VkShaderStageFlags.VK_SHADER_STAGE_FRAGMENT_BIT,
                module = fragShaderModule,
                pName  = "main".ToPointer(),
            };

            VkPipelineShaderStageCreateInfo *shaderStages = stackalloc VkPipelineShaderStageCreateInfo[] { vertShaderStageInfo, fragShaderStageInfo };

            // Vertex Input
            VkPipelineVertexInputStateCreateInfo vertexInputInfo = new VkPipelineVertexInputStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO,
                vertexBindingDescriptionCount   = 0,
                pVertexBindingDescriptions      = null, // Optional
                vertexAttributeDescriptionCount = 0,
                pVertexAttributeDescriptions    = null, // Optional
            };

            // Input assembly
            VkPipelineInputAssemblyStateCreateInfo inputAssembly = new VkPipelineInputAssemblyStateCreateInfo()
            {
                sType    = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO,
                topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
                primitiveRestartEnable = false,
            };

            // Viewports and scissors
            VkViewport viewport = new VkViewport()
            {
                x        = 0.0f,
                y        = 0.0f,
                width    = (float)swapChainExtent.width,
                height   = (float)swapChainExtent.height,
                minDepth = 0.0f,
                maxDepth = 1.0f,
            };

            VkRect2D scissor = new VkRect2D()
            {
                offset = new VkOffset2D(0, 0),
                extent = swapChainExtent,
            };

            VkPipelineViewportStateCreateInfo viewportState = new VkPipelineViewportStateCreateInfo()
            {
                sType         = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO,
                viewportCount = 1,
                pViewports    = &viewport,
                scissorCount  = 1,
                pScissors     = &scissor,
            };

            // Rasterizer
            VkPipelineRasterizationStateCreateInfo rasterizer = new VkPipelineRasterizationStateCreateInfo()
            {
                sType                   = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO,
                depthClampEnable        = false,
                rasterizerDiscardEnable = false,
                polygonMode             = VkPolygonMode.VK_POLYGON_MODE_FILL,
                lineWidth               = 1.0f,
                cullMode                = VkCullModeFlags.VK_CULL_MODE_BACK_BIT,
                frontFace               = VkFrontFace.VK_FRONT_FACE_CLOCKWISE,
                depthBiasEnable         = false,
                depthBiasConstantFactor = 0.0f, // Optional
                depthBiasClamp          = 0.0f, // Optional
                depthBiasSlopeFactor    = 0.0f, // Optional
            };

            VkPipelineMultisampleStateCreateInfo multisampling = new VkPipelineMultisampleStateCreateInfo()
            {
                sType = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO,
                sampleShadingEnable   = false,
                rasterizationSamples  = VkSampleCountFlags.VK_SAMPLE_COUNT_1_BIT,
                minSampleShading      = 1.0f,  // Optional
                pSampleMask           = null,  // Optional
                alphaToCoverageEnable = false, // Optional
                alphaToOneEnable      = false, // Optional
            };

            // Depth and Stencil testing
            //VkPipelineDepthStencilStateCreateInfo

            // Color blending
            VkPipelineColorBlendAttachmentState colorBlendAttachment = new VkPipelineColorBlendAttachmentState()
            {
                colorWriteMask = VkColorComponentFlags.VK_COLOR_COMPONENT_R_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_G_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_B_BIT |
                                 VkColorComponentFlags.VK_COLOR_COMPONENT_A_BIT,
                blendEnable         = false,
                srcColorBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ONE,  // Optional
                dstColorBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ZERO, // Optional
                colorBlendOp        = VkBlendOp.VK_BLEND_OP_ADD,          // Optional
                srcAlphaBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ONE,  // Optional
                dstAlphaBlendFactor = VkBlendFactor.VK_BLEND_FACTOR_ZERO, // Optional
                alphaBlendOp        = VkBlendOp.VK_BLEND_OP_ADD,          // Optional
            };

            VkPipelineColorBlendStateCreateInfo colorBlending = new VkPipelineColorBlendStateCreateInfo()
            {
                sType            = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO,
                logicOpEnable    = false,
                logicOp          = VkLogicOp.VK_LOGIC_OP_COPY, // Optional
                attachmentCount  = 1,
                pAttachments     = &colorBlendAttachment,
                blendConstants_0 = 0.0f, // Optional
                blendConstants_1 = 0.0f, // Optional
                blendConstants_2 = 0.0f, // Optional
                blendConstants_3 = 0.0f, // Optional
            };

            VkPipelineLayoutCreateInfo pipelineLayoutInfo = new VkPipelineLayoutCreateInfo()
            {
                sType                  = VkStructureType.VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO,
                setLayoutCount         = 0,    // Optional
                pSetLayouts            = null, // Optional
                pushConstantRangeCount = 0,    // Optional
                pPushConstantRanges    = null, // Optional
            };

            fixed(VkPipelineLayout *pipelineLayoutPtr = &pipelineLayout)
            {
                Helpers.CheckErrors(VulkanNative.vkCreatePipelineLayout(device, &pipelineLayoutInfo, null, pipelineLayoutPtr));
            }

            VkGraphicsPipelineCreateInfo pipelineInfo = new VkGraphicsPipelineCreateInfo()
            {
                sType               = VkStructureType.VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO,
                stageCount          = 2,
                pStages             = shaderStages,
                pVertexInputState   = &vertexInputInfo,
                pInputAssemblyState = &inputAssembly,
                pViewportState      = &viewportState,
                pRasterizationState = &rasterizer,
                pMultisampleState   = &multisampling,
                pDepthStencilState  = null, // Optional
                pColorBlendState    = &colorBlending,
                pDynamicState       = null, // Optional
                layout              = this.pipelineLayout,
                renderPass          = this.renderPass,
                subpass             = 0,
                basePipelineHandle  = 0,  // Optional
                basePipelineIndex   = -1, // Optional
            };

            fixed(VkPipeline *graphicsPipelinePtr = &this.graphicsPipeline)
            {
                Helpers.CheckErrors(VulkanNative.vkCreateGraphicsPipelines(this.device, 0, 1, &pipelineInfo, null, graphicsPipelinePtr));
            }

            VulkanNative.vkDestroyShaderModule(device, fragShaderModule, null);
            VulkanNative.vkDestroyShaderModule(device, vertShaderModule, null);
        }
Ejemplo n.º 30
0
        public Pipeline(Framebuffer Framebuffer, VkPipelineLayout PipelineLayout, VkShaderModule VertexShader, string VertexShaderEntryPoint, VkShaderModule FragmentShader, string FragmentShaderEntryPoint)
        {
            VkPipelineVertexInputStateCreateInfo vertexInputInfo = new VkPipelineVertexInputStateCreateInfo();

            vertexInputInfo.flags = VkPipelineVertexInputStateCreateFlag.NONE;
            vertexInputInfo.vertexAttributeDescriptions = null;
            vertexInputInfo.vertexBindingDescriptions   = null;

            VkPipelineInputAssemblyStateCreateInfo inputAssemblyInfo = new VkPipelineInputAssemblyStateCreateInfo();

            inputAssemblyInfo.flags = VkPipelineInputAssemblyStateCreateFlag.NONE;
            inputAssemblyInfo.primitiveRestartEnable = false;
            inputAssemblyInfo.topology = VkPrimitiveTopology.VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;

            VkPipelineViewportStateCreateInfo viewportInfo = new VkPipelineViewportStateCreateInfo();

            viewportInfo.flags     = VkPipelineViewportStateCreateFlag.NONE;
            viewportInfo.scissors  = new VkRect2D[] { new VkRect2D(0, 0, (uint)Framebuffer.Width, (uint)Framebuffer.Height) };
            viewportInfo.viewports = new VkViewport[] { new VkViewport(0.0f, 0.0f, (float)(Framebuffer.Width), (float)(Framebuffer.Height), 0.0f, 1.0f) };

            VkPipelineRasterizationStateCreateInfo rasterizationInfo = new VkPipelineRasterizationStateCreateInfo();

            rasterizationInfo.flags                   = VkPipelineRasterizationStateCreateFlag.NONE;
            rasterizationInfo.depthClampEnable        = false;
            rasterizationInfo.rasterizerDiscardEnable = false;
            rasterizationInfo.polygonMode             = VkPolygonMode.VK_POLYGON_MODE_FILL;
            rasterizationInfo.lineWidth               = 1.0f;
            rasterizationInfo.cullMode                = VkCullModeFlag.VK_CULL_MODE_BACK;
            rasterizationInfo.frontFace               = VkFrontFace.VK_FRONT_FACE_CLOCKWISE;
            rasterizationInfo.depthBiasEnable         = false;

            VkPipelineMultisampleStateCreateInfo multisamplingInfo = new VkPipelineMultisampleStateCreateInfo();

            multisamplingInfo.flags = VkPipelineMultisampleStateCreateFlag.NONE;
            multisamplingInfo.sampleShadingEnable  = false;
            multisamplingInfo.rasterizationSamples = VkSampleCountFlag.VK_SAMPLE_COUNT_1;

            VkPipelineColorBlendStateCreateInfo colorBlendingInfo = new VkPipelineColorBlendStateCreateInfo();

            colorBlendingInfo.flags         = VkPipelineColorBlendStateCreateFlag.NONE;
            colorBlendingInfo.logicOpEnable = false;
            colorBlendingInfo.logicOp       = VkLogicOp.VK_LOGIC_OP_COPY;
            colorBlendingInfo.attachments   = new VkPipelineColorBlendAttachmentState[] { new VkPipelineColorBlendAttachmentState()
                                                                                          {
                                                                                              colorWriteMask = VkColorComponentFlag.VK_COLOR_COMPONENT_R | VkColorComponentFlag.VK_COLOR_COMPONENT_G | VkColorComponentFlag.VK_COLOR_COMPONENT_B | VkColorComponentFlag.VK_COLOR_COMPONENT_A, blendEnable = 0
                                                                                          } };
            _Pipeline = Framebuffer.Device.CreateGraphicsPipeline(null, VkPipelineCreateFlags.NONE,
                                                                  new VkPipelineShaderStageCreateInfo[] { new VkPipelineShaderStageCreateInfo(VertexShader, VertexShaderEntryPoint, VkShaderStageFlag.VK_SHADER_STAGE_VERTEX), new VkPipelineShaderStageCreateInfo(FragmentShader, FragmentShaderEntryPoint, VkShaderStageFlag.VK_SHADER_STAGE_FRAGMENT) },
                                                                  vertexInputInfo,
                                                                  inputAssemblyInfo,
                                                                  null,
                                                                  viewportInfo,
                                                                  rasterizationInfo,
                                                                  multisamplingInfo,
                                                                  null,
                                                                  colorBlendingInfo,
                                                                  null,
                                                                  PipelineLayout,
                                                                  Framebuffer.RenderPass,
                                                                  0,
                                                                  null,
                                                                  -1
                                                                  );
        }