Пример #1
0
            public unsafe DescriptorPoolHolder(Vk api, Device device)
            {
                Api    = api;
                Device = device;

                var poolSizes = new DescriptorPoolSize[]
                {
                    new DescriptorPoolSize(DescriptorType.UniformBuffer, (1 + Constants.MaxUniformBufferBindings) * DescriptorPoolMultiplier),
                    new DescriptorPoolSize(DescriptorType.StorageBuffer, Constants.MaxStorageBufferBindings * DescriptorPoolMultiplier),
                    new DescriptorPoolSize(DescriptorType.CombinedImageSampler, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
                    new DescriptorPoolSize(DescriptorType.StorageImage, Constants.MaxImageBindings * DescriptorPoolMultiplier),
                    new DescriptorPoolSize(DescriptorType.UniformTexelBuffer, Constants.MaxTextureBindings * DescriptorPoolMultiplier),
                    new DescriptorPoolSize(DescriptorType.StorageTexelBuffer, Constants.MaxImageBindings * DescriptorPoolMultiplier)
                };

                uint maxSets = (uint)poolSizes.Length * DescriptorPoolMultiplier;

                _capacity = maxSets;

                fixed(DescriptorPoolSize *pPoolsSize = poolSizes)
                {
                    var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
                    {
                        SType         = StructureType.DescriptorPoolCreateInfo,
                        MaxSets       = maxSets,
                        PoolSizeCount = (uint)poolSizes.Length,
                        PPoolSizes    = pPoolsSize
                    };

                    Api.CreateDescriptorPool(device, descriptorPoolCreateInfo, null, out _pool).ThrowOnError();
                }
            }
Пример #2
0
        public void UpdateSetsDescriptorWrite()
        {
            const int bufferSize = 256;

            var layoutCreateInfo = new DescriptorSetLayoutCreateInfo(
                new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1));
            var poolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 1) },
                DescriptorPoolCreateFlags.FreeDescriptorSet);

            using (Buffer buffer = Device.CreateBuffer(new BufferCreateInfo(bufferSize, BufferUsages.StorageBuffer)))
                using (DeviceMemory memory = Device.AllocateMemory(new MemoryAllocateInfo(bufferSize, 0)))
                    using (DescriptorSetLayout layout = Device.CreateDescriptorSetLayout(layoutCreateInfo))
                        using (DescriptorPool pool = Device.CreateDescriptorPool(poolCreateInfo))
                            using (DescriptorSet set = pool.AllocateSets(new DescriptorSetAllocateInfo(1, layout))[0])
                            {
                                // Required to satisfy the validation layer.
                                buffer.GetMemoryRequirements();

                                buffer.BindMemory(memory);

                                var descriptorWrite = new WriteDescriptorSet(set, 0, 0, 1, DescriptorType.StorageBuffer,
                                                                             bufferInfo: new[] { new DescriptorBufferInfo(buffer) });
                                pool.UpdateSets(new[] { descriptorWrite });
                            }
        }
Пример #3
0
        private DescriptorPool CreateDescriptorPool()
        {
            DescriptorPoolSize typeCount = new DescriptorPoolSize
            {
                Type            = DescriptorType.UniformBuffer,
                DescriptorCount = 1
            };

            DescriptorPoolCreateInfo createInfo = new DescriptorPoolCreateInfo
            {
                SType         = StructureType.DescriptorPoolCreateInfo,
                MaxSets       = 1,
                PoolSizeCount = 1,
                PPoolSizes    = &typeCount,
                Flags         = DescriptorPoolCreateFlags.DescriptorPoolCreateFreeDescriptorSetBit
            };

            DescriptorPool pool;

            var res = VkApi.CreateDescriptorPool(this.Device, &createInfo, null, &pool);

            if (res != Result.Success)
            {
                throw new VMASharp.VulkanResultException("Failed to create Descriptor Pool!", res);
            }

            return(pool);
        }
Пример #4
0
        private void CreateDescriptors()
        {
            int bindingCount = Inputs.Count + 1; // + 1 output.

            // Setup bindings.
            var bindings = new DescriptorSetLayoutBinding[bindingCount];

            for (int i = 0; i < Inputs.Count; i++)
            {
                bindings[i] = Inputs[i].GetDescriptorSetLayoutBinding(i);
            }
            bindings[Inputs.Count] = Output.GetDescriptorSetLayoutBinding(Inputs.Count);

            _descriptorSetLayout = Device.Logical.CreateDescriptorSetLayout(new DescriptorSetLayoutCreateInfo(bindings));
            var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, bindingCount) });

            _descriptorPool = Device.Logical.CreateDescriptorPool(descriptorPoolCreateInfo);
            _descriptorSet  = _descriptorPool.AllocateSets(new DescriptorSetAllocateInfo(1, _descriptorSetLayout))[0];

            // Setup write descriptors.
            var writeDescriptorSets = new WriteDescriptorSet[bindingCount];

            for (int i = 0; i < Inputs.Count; i++)
            {
                writeDescriptorSets[i] = Inputs[i].GetWriteDescriptorSet(_descriptorSet, i);
            }
            writeDescriptorSets[Inputs.Count] = Output.GetWriteDescriptorSet(_descriptorSet, Inputs.Count);

            _descriptorPool.UpdateSets(writeDescriptorSets);
        }
Пример #5
0
        protected override void CreateDescriptorPool()
        {
            var poolSizes = new DescriptorPoolSize[]
            {
                new DescriptorPoolSize
                {
                    Type            = DescriptorType.UniformBuffer,
                    DescriptorCount = (uint)images.Length,
                },
                new DescriptorPoolSize
                {
                    Type            = DescriptorType.CombinedImageSampler,
                    DescriptorCount = (uint)images.Length
                }
            };

            DescriptorPoolCreateInfo poolInfo = new DescriptorPoolCreateInfo
            {
                PoolSizeCount = (uint)poolSizes.Length,
                PoolSizes     = poolSizes,
                MaxSets       = (uint)images.Length
            };

            descriptorPool = device.CreateDescriptorPool(poolInfo);
        }
Пример #6
0
        public void CreateDescriptorPool()
        {
            var createInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 2) });

            using (Device.CreateDescriptorPool(createInfo)) { }
            using (Device.CreateDescriptorPool(createInfo, CustomAllocator)) { }
        }
Пример #7
0
        DescriptorPool CreateDescriptorPool()
        {
            var poolSizes = new[]
            {
                new DescriptorPoolSize(DescriptorType.UniformBuffer, 1),
                new DescriptorPoolSize(DescriptorType.CombinedImageSampler, 1),
            };

            var createInfo = new DescriptorPoolCreateInfo(2, poolSizes);

            return(device.CreateDescriptorPool(createInfo));
        }
Пример #8
0
        public void ResetPool()
        {
            var layoutCreateInfo = new DescriptorSetLayoutCreateInfo(
                new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1));
            var poolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 1) });

            using (DescriptorSetLayout layout = Device.CreateDescriptorSetLayout(layoutCreateInfo))
                using (DescriptorPool pool = Device.CreateDescriptorPool(poolCreateInfo))
                {
                    pool.AllocateSets(new DescriptorSetAllocateInfo(1, layout));
                    pool.Reset();
                }
        }
        private void CreateDescriptorPool()
        {
            var poolSize = new DescriptorPoolSize()
            {
                Type            = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
            };

            var poolInfo = new DescriptorPoolCreateInfo()
            {
                PoolSizes = new DescriptorPoolSize[] { poolSize },
                MaxSets   = 1,
            };

            vkDescriptorPool = vkDevice.CreateDescriptorPool(poolInfo);
        }
Пример #10
0
        public void AllocateSetsAndFreeSets()
        {
            var layoutCreateInfo = new DescriptorSetLayoutCreateInfo(
                new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1));
            var poolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 1) },
                DescriptorPoolCreateFlags.FreeDescriptorSet);

            using (DescriptorSetLayout layout = Device.CreateDescriptorSetLayout(layoutCreateInfo))
                using (DescriptorPool pool = Device.CreateDescriptorPool(poolCreateInfo))
                {
                    using (pool.AllocateSets(new DescriptorSetAllocateInfo(1, layout))[0]) { }
                    DescriptorSet set = pool.AllocateSets(new DescriptorSetAllocateInfo(1, layout))[0];
                    pool.FreeSets(set);
                }
        }
Пример #11
0
        public void UpdateSetsDescriptorCopy()
        {
            var layoutCreateInfo = new DescriptorSetLayoutCreateInfo(
                new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1),
                new DescriptorSetLayoutBinding(1, DescriptorType.StorageBuffer, 1));
            var poolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 2) });

            using (DescriptorSetLayout layout = Device.CreateDescriptorSetLayout(layoutCreateInfo))
                using (DescriptorPool pool = Device.CreateDescriptorPool(poolCreateInfo))
                {
                    DescriptorSet set = pool.AllocateSets(new DescriptorSetAllocateInfo(1, layout))[0];
                    // It is valid to copy from self to self (without overlapping memory boundaries).
                    var descriptorCopy = new CopyDescriptorSet(set, 0, 0, set, 1, 0, 1);
                    pool.UpdateSets(descriptorCopies: new[] { descriptorCopy });
                }
        }
Пример #12
0
        DescriptorSet[] CreateDescriptorSets()
        {
            var typeCount = new DescriptorPoolSize {
                Type            = DescriptorType.UniformBuffer,
                DescriptorCount = 1
            };
            var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo {
                PoolSizes = new DescriptorPoolSize [] { typeCount },
                MaxSets   = 1
            };
            var descriptorPool = device.CreateDescriptorPool(descriptorPoolCreateInfo);

            var descriptorSetAllocateInfo = new DescriptorSetAllocateInfo {
                SetLayouts     = new DescriptorSetLayout [] { descriptorSetLayout },
                DescriptorPool = descriptorPool
            };

            return(device.AllocateDescriptorSets(descriptorSetAllocateInfo));
        }
            public DescriptorPoolObject(Device myDevice)
            {
                myEnumValues = (DescriptorType[])Enum.GetValues(typeof(DescriptorType));
                int PoolItems = myEnumValues.Count();

                DescriptorPoolSize[] myPoolSizeValues = new DescriptorPoolSize[PoolItems];
                DescriptorSetTypesRemainingInPool = new uint[PoolItems];
                for (int i = 0; i < myEnumValues.Length; i++)
                {
                    myPoolSizeValues[i].Type             = (DescriptorType)myEnumValues[i];
                    myPoolSizeValues[i].DescriptorCount  = 100;
                    DescriptorSetTypesRemainingInPool[i] = 100;
                }
                DescriptorPoolCreateInfo myCreateInformation = new DescriptorPoolCreateInfo();

                //TODO: Deallocate
                myCreateInformation.MaxSets   = TotalSetsRemaining;
                myCreateInformation.PoolSizes = myPoolSizeValues;
                myNewPoolObject = myDevice.CreateDescriptorPool(myCreateInformation);
            }
Пример #14
0
        public unsafe DescriptorPool(Api api, Span <DescriptorBinding> descriptorBindings, ulong maxSets)
        {
            _api = api;

            Span <DescriptorPoolSize> poolSizes = stackalloc DescriptorPoolSize[descriptorBindings.Length];

            for (int i = 0; i < descriptorBindings.Length; i++)
            {
                poolSizes[i] = new DescriptorPoolSize(descriptorBindings[i].Type, descriptorBindings[i].DescriptorCount * (uint)maxSets);
            }

            var poolInfo = new DescriptorPoolCreateInfo();

            poolInfo.SType         = StructureType.DescriptorPoolCreateInfo;
            poolInfo.PoolSizeCount = (uint)poolSizes.Length;
            poolInfo.PPoolSizes    = (DescriptorPoolSize *)Unsafe.AsPointer(ref poolSizes[0]);
            poolInfo.MaxSets       = (uint)maxSets;
            poolInfo.Flags         = DescriptorPoolCreateFlags.DescriptorPoolCreateFreeDescriptorSetBit;

            Util.Verify(_api.Vk.CreateDescriptorPool(_api.Device.VkDevice, poolInfo, default, out _vkDescriptorPool), $"{nameof(DescriptorPool)}: Unable to create descriptor pool");
Пример #15
0
        protected override unsafe SharpVulkan.DescriptorPool CreateObject()
        {
            // No allocator ready to be used, let's create a new one
            var poolSizes = GraphicsDevice.MaxDescriptorTypeCounts
                            .Select((count, index) => new DescriptorPoolSize {
                Type = (DescriptorType)index, DescriptorCount = count
            })
                            .Where(size => size.DescriptorCount > 0)
                            .ToArray();

            var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo
            {
                StructureType = StructureType.DescriptorPoolCreateInfo,
                PoolSizeCount = (uint)poolSizes.Length,
                PoolSizes     = new IntPtr(Interop.Fixed(poolSizes)),
                MaxSets       = GraphicsDevice.MaxDescriptorSetCount,
            };

            return(GraphicsDevice.NativeDevice.CreateDescriptorPool(ref descriptorPoolCreateInfo));
        }
Пример #16
0
        public void CmdBindDescriptorSet()
        {
            const int bufferSize = 256;

            var layoutCreateInfo = new DescriptorSetLayoutCreateInfo(
                new DescriptorSetLayoutBinding(0, DescriptorType.StorageBuffer, 1));
            var descriptorPoolCreateInfo = new DescriptorPoolCreateInfo(
                1,
                new[] { new DescriptorPoolSize(DescriptorType.StorageBuffer, 1) });

            using (DescriptorSetLayout descriptorSetLayout = Device.CreateDescriptorSetLayout(layoutCreateInfo))
                using (DescriptorPool descriptorPool = Device.CreateDescriptorPool(descriptorPoolCreateInfo))
                    using (PipelineLayout pipelineLayout = Device.CreatePipelineLayout(new PipelineLayoutCreateInfo(new[] { descriptorSetLayout })))
                        using (Buffer buffer = Device.CreateBuffer(new BufferCreateInfo(bufferSize, BufferUsages.StorageBuffer)))
                            using (DeviceMemory memory = Device.AllocateMemory(new MemoryAllocateInfo(bufferSize, 0)))
                            {
                                // Required to satisfy the validation layer.
                                buffer.GetMemoryRequirements();

                                buffer.BindMemory(memory);

                                DescriptorSet descriptorSet =
                                    descriptorPool.AllocateSets(new DescriptorSetAllocateInfo(1, descriptorSetLayout))[0];

                                var descriptorWrite = new WriteDescriptorSet(descriptorSet, 0, 0, 1, DescriptorType.StorageBuffer,
                                                                             bufferInfo: new[] { new DescriptorBufferInfo(buffer) });

                                descriptorPool.UpdateSets(new[] { descriptorWrite });

                                CommandBuffer.Begin();
                                CommandBuffer.CmdBindDescriptorSet(PipelineBindPoint.Graphics, pipelineLayout, descriptorSet);
                                CommandBuffer.CmdBindDescriptorSets(PipelineBindPoint.Graphics, pipelineLayout, 0, new[] { descriptorSet });
                                CommandBuffer.End();

                                descriptorPool.Reset();
                            }
        }
Пример #17
0
        private unsafe void CreatePipelineLayout()
        {
            var binding = new DescriptorSetLayoutBinding
            {
                Binding = 0,
                DescriptorCount = 1,
                DescriptorType = DescriptorType.UniformBuffer,
                StageFlags = ShaderStageFlags.Vertex
            };

            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount = 1,
                Bindings = new IntPtr(&binding)
            };
            descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo);

            var localDescriptorSetLayout = descriptorSetLayout;
            var createInfo = new PipelineLayoutCreateInfo
            {
                StructureType = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts = new IntPtr(&localDescriptorSetLayout)
            };
            pipelineLayout = device.CreatePipelineLayout(ref createInfo);

            var poolSize = new DescriptorPoolSize { DescriptorCount = 2, Type = DescriptorType.UniformBuffer };
            var descriptorPoolCreateinfo = new DescriptorPoolCreateInfo
            {
                StructureType = StructureType.DescriptorPoolCreateInfo,
                PoolSizeCount = 1,
                PoolSizes = new IntPtr(&poolSize),
                MaxSets = 2
            };
            descriptorPool = device.CreateDescriptorPool(ref descriptorPoolCreateinfo);

            var bufferCreateInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Usage = BufferUsageFlags.UniformBuffer,
                Size = 64,
            };
            uniformBuffer = device.CreateBuffer(ref bufferCreateInfo);

            MemoryRequirements memoryRequirements;
            device.GetBufferMemoryRequirements(uniformBuffer, out memoryRequirements);
            var memory = AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements);

            device.BindBufferMemory(uniformBuffer, memory, 0);

            var mappedMemory = device.MapMemory(memory, 0, 64, MemoryMapFlags.None);
            var data = new[]
            {
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f,
            };
            Utilities.Write(mappedMemory, data, 0, data.Length);
            device.UnmapMemory(memory);
        }
Пример #18
0
 internal static unsafe extern Result vkCreateDescriptorPool(Device device, DescriptorPoolCreateInfo* createInfo, AllocationCallbacks* allocator, DescriptorPool* descriptorPool);
Пример #19
0
        void CreateDescriptorSet()
        {
            /*
             * So we will allocate a descriptor set here.
             * But we need to first create a descriptor pool to do that.
             */

            /*
             * Our descriptor pool can only allocate a single storage buffer.
             */
            DescriptorPoolSize descriptorPoolSize = new DescriptorPoolSize()
            {
                Type            = DescriptorType.StorageBuffer,// VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
                DescriptorCount = 1
            };
            DescriptorPoolCreateInfo descriptorPoolCreateInfo = new DescriptorPoolCreateInfo()
            {
                MaxSets   = 1, // we only need to allocate one descriptor set from the pool.
                Flags     = DescriptorPoolCreateFlags.FreeDescriptorSet,
                PoolSizes = new[] { descriptorPoolSize }
            };

            // create descriptor pool.
            descriptorPool = device.CreateDescriptorPool(descriptorPoolCreateInfo);

            /*
             * With the pool allocated, we can now allocate the descriptor set.
             */
            DescriptorSetAllocateInfo descriptorSetAllocateInfo = new DescriptorSetAllocateInfo(1, descriptorSetLayout);

            // allocate a single descriptor set.

            // allocate descriptor set.
            descriptorSet = descriptorPool.AllocateSets(descriptorSetAllocateInfo)[0];

            /*
             * Next, we need to connect our actual storage buffer with the descrptor.
             * We use vkUpdateDescriptorSets() to update the descriptor set.
             */

            // Specify the buffer to bind to the descriptor.
            DescriptorBufferInfo descriptorBufferInfo = new DescriptorBufferInfo()
            {
                Buffer = buffer,
                Offset = 0,
                Range  = bufferSize
            };
            WriteDescriptorSet writeDescriptorSet = new WriteDescriptorSet()
            {
                DstSet          = descriptorSet,                // write to this descriptor set.
                DstBinding      = 0,                            // write to the first, and only binding.
                DstArrayElement = 0,
                DescriptorCount = 1,                            // update a single descriptor.
                DescriptorType  = DescriptorType.StorageBuffer, // VK_DESCRIPTOR_TYPE_STORAGE_BUFFER; // storage buffer.
                BufferInfo      = new[] { descriptorBufferInfo }
            };

            // perform the update of the descriptor set.
            WriteDescriptorSet[] k = { writeDescriptorSet };
            descriptorPool.UpdateSets(k);
        }
Пример #20
0
        public bool CreateSwapChain(DrunkSpock spock,
                                    int extentX, int extentY)
        {
            PhysicalDevice phys = mLogical.Parent;
            SurfaceKhr     surf = spock.GetSurface();

            SurfaceCapabilitiesKhr surfCaps = phys.GetSurfaceCapabilitiesKhr(surf);

            SurfaceFormatKhr                [] surfFormats = phys.GetSurfaceFormatsKhr(surf);
            PresentModeKhr                  [] presModes   = phys.GetSurfacePresentModesKhr(surf);

            if (surfFormats.Length <= 0 || presModes.Length <= 0)
            {
                Misc.SafeInvoke(eErrorSpam, "Bad formats or pres modes...");
                return(false);
            }

            mSwapExtent = new Extent2D(extentX, extentY);

            int imageCount = surfCaps.MinImageCount + 1;

            if (surfCaps.MaxImageCount > 0 && imageCount > surfCaps.MaxImageCount)
            {
                imageCount = surfCaps.MaxImageCount;
            }

            SwapchainCreateInfoKhr scci = new SwapchainCreateInfoKhr(
                surf, Format.B8G8R8A8UNorm, mSwapExtent,
                imageCount, ColorSpaceKhr.SRgbNonlinear, 1,
                ImageUsages.ColorAttachment);

            scci.ImageSharingMode = SharingMode.Exclusive;

            if (presModes.Contains(PresentModeKhr.Mailbox))
            {
                scci.PresentMode = PresentModeKhr.Mailbox;
            }

            mSwapChain = mLogical.CreateSwapchainKhr(scci);
            if (mSwapChain == null)
            {
                Misc.SafeInvoke(eErrorSpam, "Create swap chain failed...");
                return(false);
            }

            VulkanCore.Image        [] chainImages = mSwapChain.GetImages();

            mChainImageViews = new ImageView[chainImages.Length];

            for (int i = 0; i < chainImages.Length; i++)
            {
                ImageSubresourceRange isr = new ImageSubresourceRange(
                    ImageAspects.Color, 0, 1, 0, 1);

                ImageViewCreateInfo ivci = new ImageViewCreateInfo(
                    mSwapChain.Format, isr);

                mChainImageViews[i] = chainImages[i].CreateView(ivci);
            }

            //descriptor pool stuff
            DescriptorPoolSize dps = new DescriptorPoolSize(
                DescriptorType.UniformBuffer, chainImages.Length);

            DescriptorPoolCreateInfo dpci = new DescriptorPoolCreateInfo();

            dpci.PoolSizes = new DescriptorPoolSize[] { dps };
            dpci.MaxSets   = chainImages.Length;

            mDPool = mLogical.CreateDescriptorPool(dpci);

            return(true);
        }
Пример #21
0
 public unsafe DescriptorPool CreateDescriptorPool(ref DescriptorPoolCreateInfo createInfo, AllocationCallbacks* allocator = null)
 {
     DescriptorPool descriptorPool;
     fixed (DescriptorPoolCreateInfo* __createInfo__ = &createInfo)
     {
         vkCreateDescriptorPool(this, __createInfo__, allocator, &descriptorPool).CheckError();
     }
     return descriptorPool;
 }
Пример #22
0
        private unsafe void CreatePipelineLayout()
        {
            var binding = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorCount = 1,
                DescriptorType  = DescriptorType.UniformBuffer,
                StageFlags      = ShaderStageFlags.Vertex
            };

            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount  = 1,
                Bindings      = new IntPtr(&binding)
            };

            descriptorSetLayout = device.CreateDescriptorSetLayout(ref descriptorSetLayoutCreateInfo);

            var localDescriptorSetLayout = descriptorSetLayout;
            var createInfo = new PipelineLayoutCreateInfo
            {
                StructureType  = StructureType.PipelineLayoutCreateInfo,
                SetLayoutCount = 1,
                SetLayouts     = new IntPtr(&localDescriptorSetLayout)
            };

            pipelineLayout = device.CreatePipelineLayout(ref createInfo);

            var poolSize = new DescriptorPoolSize {
                DescriptorCount = 2, Type = DescriptorType.UniformBuffer
            };
            var descriptorPoolCreateinfo = new DescriptorPoolCreateInfo
            {
                StructureType = StructureType.DescriptorPoolCreateInfo,
                PoolSizeCount = 1,
                PoolSizes     = new IntPtr(&poolSize),
                MaxSets       = 2
            };

            descriptorPool = device.CreateDescriptorPool(ref descriptorPoolCreateinfo);

            var bufferCreateInfo = new BufferCreateInfo
            {
                StructureType = StructureType.BufferCreateInfo,
                Usage         = BufferUsageFlags.UniformBuffer,
                Size          = 64,
            };

            uniformBuffer = device.CreateBuffer(ref bufferCreateInfo);

            MemoryRequirements memoryRequirements;

            device.GetBufferMemoryRequirements(uniformBuffer, out memoryRequirements);
            var memory = AllocateMemory(MemoryPropertyFlags.HostVisible | MemoryPropertyFlags.HostCoherent, memoryRequirements);

            device.BindBufferMemory(uniformBuffer, memory, 0);

            var mappedMemory = device.MapMemory(memory, 0, 64, MemoryMapFlags.None);
            var data         = new[]
            {
                1.0f, 0.0f, 0.0f, 0.0f,
                0.0f, 1.0f, 0.0f, 0.0f,
                0.0f, 0.0f, 1.0f, 0.0f,
                0.0f, 0.0f, 0.0f, 1.0f,
            };

            Utilities.Write(mappedMemory, data, 0, data.Length);
            device.UnmapMemory(memory);
        }