Beispiel #1
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);
        }
        void CreateDescriptorSetLayout()
        {
            /*
             * Here we specify a descriptor set layout. This allows us to bind our descriptors to
             * resources in the shader.
             */

            /*
             * Here we specify a binding of type VK_DESCRIPTOR_TYPE_STORAGE_BUFFER to the binding point
             * 0. This binds to
             * layout(std140, binding = 0) buffer buf
             * in the compute shader.
             */
            DescriptorSetLayoutBinding descriptorSetLayoutBinding = new DescriptorSetLayoutBinding()
            {
                Binding         = 0,                            // binding = 0
                DescriptorType  = DescriptorType.StorageBuffer, // VK_DESCRIPTOR_TYPE_STORAGE_BUFFER;
                DescriptorCount = 1,
                StageFlags      = ShaderStages.Compute          // VK_SHADER_STAGE_COMPUTE_BIT;
            };
            DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo();

            // descriptorSetLayoutCreateInfo.bindingCount = 1; // only a single binding in this descriptor set layout.
            DescriptorSetLayoutBinding[] temp = { descriptorSetLayoutBinding };
            descriptorSetLayoutCreateInfo.Bindings = temp;

            // Create the descriptor set layout.
            descriptorSetLayout = device.CreateDescriptorSetLayout(descriptorSetLayoutCreateInfo);
        }
        private DescriptorSetLayout[] CreateDescriptorSetLayouts()
        {
            DescriptorSetLayoutBinding binding = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageVertexBit
            };

            DescriptorSetLayoutCreateInfo createInfo = new DescriptorSetLayoutCreateInfo
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount = 1,
                PBindings    = &binding
            };

            DescriptorSetLayout layout;
            var res = VkApi.CreateDescriptorSetLayout(this.Device, &createInfo, null, &layout);

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

            return(new[] { layout });
        }
Beispiel #4
0
        protected override void CreateDescriptorSetLayout()
        {
            var uboLayoutBinding = new DescriptorSetLayoutBinding
            {
                Binding           = 0,
                DescriptorType    = DescriptorType.UniformBuffer,
                DescriptorCount   = 1,
                ImmutableSamplers = null,
                StageFlags        = ShaderStageFlags.Vertex
            };

            var samplerLayoutBinding = new DescriptorSetLayoutBinding
            {
                Binding           = 1,
                DescriptorCount   = 1,
                DescriptorType    = DescriptorType.CombinedImageSampler,
                ImmutableSamplers = null,
                StageFlags        = ShaderStageFlags.Fragment
            };

            var bindings = new[] { uboLayoutBinding, samplerLayoutBinding };

            var layoutInfo = new DescriptorSetLayoutCreateInfo
            {
                BindingCount = (uint)bindings.Length,
                Bindings     = bindings,
            };

            descriptorSetLayout = device.CreateDescriptorSetLayout(layoutInfo);
        }
Beispiel #5
0
        protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout)
        {
            DescriptorSetLayoutBinding uLayoutBindings = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageVertexBit
            };

            DescriptorSetLayoutBinding tLayoutBindings = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.CombinedImageSampler,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageFragmentBit
            };

            DescriptorSetLayout[] layouts = new DescriptorSetLayout[3];

            var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = &uLayoutBindings,
                BindingCount = 1
            };

            var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                BindingCount = 0
            };

            var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = &tLayoutBindings,
                BindingCount = 1
            };

            gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[0]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[1]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[2]).ThrowOnError();

            fixed(DescriptorSetLayout *pLayouts = layouts)
            {
                var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
                {
                    SType          = StructureType.PipelineLayoutCreateInfo,
                    PSetLayouts    = pLayouts,
                    SetLayoutCount = 3
                };

                gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
            }

            return(layouts);
        }
Beispiel #6
0
        internal static unsafe SharpVulkan.DescriptorSetLayout CreateNativeDescriptorSetLayout(GraphicsDevice device, IList <DescriptorSetLayoutBuilder.Entry> entries, out uint[] typeCounts)
        {
            var bindings          = new DescriptorSetLayoutBinding[entries.Count];
            var immutableSamplers = new Sampler[entries.Count];

            int usedBindingCount = 0;

            typeCounts = new uint[DescriptorTypeCount];

            fixed(Sampler *immutableSamplersPointer = &immutableSamplers[0])
            {
                for (int i = 0; i < entries.Count; i++)
                {
                    var entry = entries[i];

                    // TODO VULKAN: Special case for unused bindings in PipelineState. Handle more nicely.
                    if (entry.ArraySize == 0)
                    {
                        continue;
                    }

                    bindings[usedBindingCount] = new DescriptorSetLayoutBinding
                    {
                        DescriptorType  = VulkanConvertExtensions.ConvertDescriptorType(entry.Class, entry.Type),
                        StageFlags      = ShaderStageFlags.All, // TODO VULKAN: Filter?
                        Binding         = (uint)i,
                        DescriptorCount = (uint)entry.ArraySize
                    };

                    if (entry.ImmutableSampler != null)
                    {
                        // TODO VULKAN: Handle immutable samplers for DescriptorCount > 1
                        if (entry.ArraySize > 1)
                        {
                            throw new NotImplementedException();
                        }

                        // Remember this, so we can choose the right DescriptorType in DescriptorSet.SetShaderResourceView
                        immutableSamplers[i] = entry.ImmutableSampler.NativeSampler;
                        //bindings[i].DescriptorType = DescriptorType.CombinedImageSampler;
                        bindings[usedBindingCount].ImmutableSamplers = new IntPtr(immutableSamplersPointer + i);
                    }

                    typeCounts[(int)bindings[usedBindingCount].DescriptorType] += bindings[usedBindingCount].DescriptorCount;

                    usedBindingCount++;
                }

                var createInfo = new DescriptorSetLayoutCreateInfo
                {
                    StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                    BindingCount  = (uint)usedBindingCount,
                    Bindings      = usedBindingCount > 0 ? new IntPtr(Interop.Fixed(bindings)) : IntPtr.Zero
                };

                return(device.NativeDevice.CreateDescriptorSetLayout(ref createInfo));
            }
        }
        internal static unsafe SharpVulkan.DescriptorSetLayout CreateNativeDescriptorSetLayout(GraphicsDevice device, IList<DescriptorSetLayoutBuilder.Entry> entries, out uint[] typeCounts)
        {
            var bindings = new DescriptorSetLayoutBinding[entries.Count];
            var immutableSamplers = new Sampler[entries.Count];

            int usedBindingCount = 0;

            typeCounts = new uint[DescriptorTypeCount];

            fixed (Sampler* immutableSamplersPointer = &immutableSamplers[0])
            {
                for (int i = 0; i < entries.Count; i++)
                {
                    var entry = entries[i];

                    // TODO VULKAN: Special case for unused bindings in PipelineState. Handle more nicely.
                    if (entry.ArraySize == 0)
                        continue;

                    bindings[usedBindingCount] = new DescriptorSetLayoutBinding
                    {
                        DescriptorType = VulkanConvertExtensions.ConvertDescriptorType(entry.Class, entry.Type),
                        StageFlags = ShaderStageFlags.All, // TODO VULKAN: Filter?
                        Binding = (uint)i,
                        DescriptorCount = (uint)entry.ArraySize
                    };

                    if (entry.ImmutableSampler != null)
                    {
                        // TODO VULKAN: Handle immutable samplers for DescriptorCount > 1
                        if (entry.ArraySize > 1)
                        {
                            throw new NotImplementedException();
                        }

                        // Remember this, so we can choose the right DescriptorType in DescriptorSet.SetShaderResourceView
                        immutableSamplers[i] = entry.ImmutableSampler.NativeSampler;
                        //bindings[i].DescriptorType = DescriptorType.CombinedImageSampler;
                        bindings[usedBindingCount].ImmutableSamplers = new IntPtr(immutableSamplersPointer + i);
                    }

                    typeCounts[(int)bindings[usedBindingCount].DescriptorType] += bindings[usedBindingCount].DescriptorCount;

                    usedBindingCount++;
                }

                var createInfo = new DescriptorSetLayoutCreateInfo
                {
                    StructureType = StructureType.DescriptorSetLayoutCreateInfo,
                    BindingCount = (uint)usedBindingCount,
                    Bindings = usedBindingCount > 0 ? new IntPtr(Interop.Fixed(bindings)) : IntPtr.Zero
                };
                return device.NativeDevice.CreateDescriptorSetLayout(ref createInfo);
            }
        }
Beispiel #8
0
        DescriptorSetLayout CreateDescriptorSetLayout()
        {
            var layoutBinding = new DescriptorSetLayoutBinding {
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.Vertex
            };
            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo {
                Bindings = new DescriptorSetLayoutBinding [] { layoutBinding }
            };

            return(device.CreateDescriptorSetLayout(descriptorSetLayoutCreateInfo));
        }
        private void CreateDescriptorSetLayout()
        {
            var uboLayoutBinding = new DescriptorSetLayoutBinding()
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.Vertex,
            };

            var layoutInfo = new DescriptorSetLayoutCreateInfo()
            {
                BindingCount = 1,
                Bindings     = new DescriptorSetLayoutBinding[] { uboLayoutBinding },
            };

            vkDescriptorSetLayout = vkDevice.CreateDescriptorSetLayout(layoutInfo);
        }
Beispiel #10
0
            private static DescriptorSetLayout CreateLayout(
                Device logicalDevice, ReadOnlySpan <IShaderInput> inputs)
            {
                var bindings = new DescriptorSetLayoutBinding[inputs.Length];

                for (int i = 0; i < bindings.Length; i++)
                {
                    bindings[i] = new DescriptorSetLayoutBinding(
                        binding: i,
                        descriptorType: inputs[i].DescriptorType,
                        descriptorCount: 1,
                        //NOTE: At the moment all resources are bound in both the vertex and the fragment
                        //shader, this is the most user friendly setup. Need to do some profiling to
                        //see if this is hurting the performance
                        stageFlags: ShaderStages.Vertex | ShaderStages.Fragment);
                }
                return(logicalDevice.CreateDescriptorSetLayout(new DescriptorSetLayoutCreateInfo(
                                                                   bindings)));
            }
Beispiel #11
0
        public DescriptorSetLayout GetDescriptorSetLayout()
        {
            List <DescriptorSetLayoutBinding> myBindings = new List <DescriptorSetLayoutBinding>();

            foreach (var A in myBindingNumberToItems)
            {
                var Item = new DescriptorSetLayoutBinding();
                Item.DescriptorType  = (DescriptorType)A.Value.myType;
                Item.StageFlags      = A.Value.ShaderStage;
                Item.DescriptorCount = A.Value.DescriptorCount;
                Item.Binding         = A.Value.Binding;
                myBindings.Add(Item);
            }
            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                Bindings = myBindings.ToArray()
            };

            return(new DescriptorSetLayout(VulkanRenderer.SelectedLogicalDevice, descriptorSetLayoutCreateInfo));
        }
Beispiel #12
0
        public void CreateDescriptorLayout()
        {
            DescriptorSetLayoutBinding dslb = new DescriptorSetLayoutBinding();

            dslb.Binding         = 0;
            dslb.DescriptorType  = DescriptorType.UniformBuffer;
            dslb.DescriptorCount = 1;
            dslb.StageFlags      = ShaderStages.Vertex;

            DescriptorSetLayoutCreateInfo dslci = new DescriptorSetLayoutCreateInfo();

            dslci.Bindings = new DescriptorSetLayoutBinding[] { dslb };

            mDSLs = new DescriptorSetLayout[mChainImageViews.Length];

            for (int i = 0; i < mChainImageViews.Length; i++)
            {
                mDSLs[i] = mLogical.CreateDescriptorSetLayout(dslci);
            }
        }
Beispiel #13
0
        public static DescriptorSetLayout CreateDescriptorSetLayout(Graphics g, DescriptorItem[] items)
        {
            var bindings = new DescriptorSetLayoutBinding[items.Length];

            for (var i = 0; i < items.Length; i++)
            {
                var item = items[i];
                bindings[i] = new DescriptorSetLayoutBinding(
                    i,
                    item.Type == DescriptorItem.DescriptorType.UniformBuffer ? DescriptorType.UniformBuffer :
                    item.Type == DescriptorItem.DescriptorType.CombinedImageSampler ? DescriptorType.CombinedImageSampler :
                    DescriptorType.UniformBuffer,
                    item.Count,
                    item.Shader == DescriptorItem.ShaderType.Vertex ? ShaderStages.Vertex :
                    item.Shader == DescriptorItem.ShaderType.Fragment ? ShaderStages.Fragment :
                    ShaderStages.All
                    );
            }
            return(g.Context.Device.CreateDescriptorSetLayout(new DescriptorSetLayoutCreateInfo(bindings)));
        }
        public DescriptorSetLayout(Device selectedDevice)
        {
            AllocationCallbacks pAllocator = null;

            this.selectedDevice = selectedDevice;

            var layoutBinding = new DescriptorSetLayoutBinding
            {
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.Vertex
            };


            var descriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo
            {
                Bindings = new DescriptorSetLayoutBinding[] { layoutBinding }
            };

            Result result;

            //DescriptorSetLayout pSetLayout;
            unsafe
            {
                //pSetLayout = new DescriptorSetLayout();

                fixed(UInt64 *ptrpSetLayout = &this.m)
                {
                    result = Interop.NativeMethods.vkCreateDescriptorSetLayout(selectedDevice.Handle, descriptorSetLayoutCreateInfo != null ? descriptorSetLayoutCreateInfo.m : (Interop.DescriptorSetLayoutCreateInfo *) default(IntPtr), pAllocator != null ? pAllocator.m : null, ptrpSetLayout);
                }

                if (result != Result.Success)
                {
                    throw new ResultException(result);
                }
            }
        }
Beispiel #15
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);
        }
Beispiel #16
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);
        }
Beispiel #17
0
        public static unsafe DescriptorSetLayout[] Create(VulkanGraphicsDevice gd, Device device, uint stages, out PipelineLayout layout)
        {
            int stagesCount = BitOperations.PopCount(stages);

            int uCount  = Constants.MaxUniformBuffersPerStage * stagesCount + 1;
            int tCount  = Constants.MaxTexturesPerStage * stagesCount;
            int iCount  = Constants.MaxImagesPerStage * stagesCount;
            int bTCount = tCount;
            int bICount = iCount;

            DescriptorSetLayoutBinding *uLayoutBindings  = stackalloc DescriptorSetLayoutBinding[uCount];
            DescriptorSetLayoutBinding *sLayoutBindings  = stackalloc DescriptorSetLayoutBinding[stagesCount];
            DescriptorSetLayoutBinding *tLayoutBindings  = stackalloc DescriptorSetLayoutBinding[tCount];
            DescriptorSetLayoutBinding *iLayoutBindings  = stackalloc DescriptorSetLayoutBinding[iCount];
            DescriptorSetLayoutBinding *bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[bTCount];
            DescriptorSetLayoutBinding *bILayoutBindings = stackalloc DescriptorSetLayoutBinding[bICount];

            uLayoutBindings[0] = new DescriptorSetLayoutBinding
            {
                Binding         = 0,
                DescriptorType  = DescriptorType.UniformBuffer,
                DescriptorCount = 1,
                StageFlags      = ShaderStageFlags.ShaderStageFragmentBit | ShaderStageFlags.ShaderStageComputeBit
            };

            int iter = 0;

            while (stages != 0)
            {
                int stage = BitOperations.TrailingZeroCount(stages);
                stages &= ~(1u << stage);

                var stageFlags = stage switch
                {
                    1 => ShaderStageFlags.ShaderStageFragmentBit,
                    2 => ShaderStageFlags.ShaderStageGeometryBit,
                    3 => ShaderStageFlags.ShaderStageTessellationControlBit,
                    4 => ShaderStageFlags.ShaderStageTessellationEvaluationBit,
                    _ => ShaderStageFlags.ShaderStageVertexBit | ShaderStageFlags.ShaderStageComputeBit
                };

                void Set(DescriptorSetLayoutBinding *bindings, int maxPerStage, DescriptorType type, int start = 0)
                {
                    for (int i = 0; i < maxPerStage; i++)
                    {
                        bindings[start + iter * maxPerStage + i] = new DescriptorSetLayoutBinding
                        {
                            Binding         = (uint)(start + stage * maxPerStage + i),
                            DescriptorType  = type,
                            DescriptorCount = 1,
                            StageFlags      = stageFlags
                        };
                    }
                }

                void SetStorage(DescriptorSetLayoutBinding *bindings, int maxPerStage, int start = 0)
                {
                    bindings[start + iter] = new DescriptorSetLayoutBinding
                    {
                        Binding         = (uint)(start + stage * maxPerStage),
                        DescriptorType  = DescriptorType.StorageBuffer,
                        DescriptorCount = (uint)maxPerStage,
                        StageFlags      = stageFlags
                    };
                }

                Set(uLayoutBindings, Constants.MaxUniformBuffersPerStage, DescriptorType.UniformBuffer, 1);
                SetStorage(sLayoutBindings, Constants.MaxStorageBuffersPerStage);
                Set(tLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.CombinedImageSampler);
                Set(iLayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageImage);
                Set(bTLayoutBindings, Constants.MaxTexturesPerStage, DescriptorType.UniformTexelBuffer);
                Set(bILayoutBindings, Constants.MaxImagesPerStage, DescriptorType.StorageTexelBuffer);

                iter++;
            }

            DescriptorSetLayout[] layouts = new DescriptorSetLayout[PipelineFull.DescriptorSetLayouts];

            var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = uLayoutBindings,
                BindingCount = (uint)uCount
            };

            var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = sLayoutBindings,
                BindingCount = (uint)stagesCount
            };

            var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = tLayoutBindings,
                BindingCount = (uint)tCount
            };

            var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = iLayoutBindings,
                BindingCount = (uint)iCount
            };

            var bTDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = bTLayoutBindings,
                BindingCount = (uint)bTCount
            };

            var bIDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = bILayoutBindings,
                BindingCount = (uint)bICount
            };

            gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.UniformSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.TextureSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.ImageSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, bTDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferTextureSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, bIDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.BufferImageSetIndex]).ThrowOnError();

            fixed(DescriptorSetLayout *pLayouts = layouts)
            {
                var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
                {
                    SType          = StructureType.PipelineLayoutCreateInfo,
                    PSetLayouts    = pLayouts,
                    SetLayoutCount = PipelineFull.DescriptorSetLayouts
                };

                gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
            }

            return(layouts);
        }
    }
Beispiel #18
0
        public static unsafe DescriptorSetLayout[] CreateMinimal(VulkanRenderer gd, Device device, ShaderSource[] shaders, out PipelineLayout layout)
        {
            int stagesCount = shaders.Length;

            int uCount = 0;
            int tCount = 0;
            int iCount = 0;

            foreach (var shader in shaders)
            {
                uCount += shader.Bindings.UniformBufferBindings.Count;
                tCount += shader.Bindings.TextureBindings.Count;
                iCount += shader.Bindings.ImageBindings.Count;
            }

            DescriptorSetLayoutBinding *uLayoutBindings = stackalloc DescriptorSetLayoutBinding[uCount];
            DescriptorSetLayoutBinding *sLayoutBindings = stackalloc DescriptorSetLayoutBinding[stagesCount];
            DescriptorSetLayoutBinding *tLayoutBindings = stackalloc DescriptorSetLayoutBinding[tCount];
            DescriptorSetLayoutBinding *iLayoutBindings = stackalloc DescriptorSetLayoutBinding[iCount];

            int uIndex = 0;
            int sIndex = 0;
            int tIndex = 0;
            int iIndex = 0;

            foreach (var shader in shaders)
            {
                var stageFlags = shader.Stage.Convert();

                void Set(DescriptorSetLayoutBinding *bindings, DescriptorType type, ref int start, IEnumerable <int> bds)
                {
                    foreach (var b in bds)
                    {
                        bindings[start++] = new DescriptorSetLayoutBinding
                        {
                            Binding         = (uint)b,
                            DescriptorType  = type,
                            DescriptorCount = 1,
                            StageFlags      = stageFlags
                        };
                    }
                }

                void SetStorage(DescriptorSetLayoutBinding *bindings, ref int start, int count)
                {
                    bindings[start++] = new DescriptorSetLayoutBinding
                    {
                        Binding         = (uint)start,
                        DescriptorType  = DescriptorType.StorageBuffer,
                        DescriptorCount = (uint)count,
                        StageFlags      = stageFlags
                    };
                }

                // TODO: Support buffer textures and images here.
                // This is only used for the helper shaders on the backend, and we don't use buffer textures on them
                // so far, so it's not really necessary right now.
                Set(uLayoutBindings, DescriptorType.UniformBuffer, ref uIndex, shader.Bindings.UniformBufferBindings);
                SetStorage(sLayoutBindings, ref sIndex, shader.Bindings.StorageBufferBindings.Count);
                Set(tLayoutBindings, DescriptorType.CombinedImageSampler, ref tIndex, shader.Bindings.TextureBindings);
                Set(iLayoutBindings, DescriptorType.StorageImage, ref iIndex, shader.Bindings.ImageBindings);
            }

            DescriptorSetLayout[] layouts = new DescriptorSetLayout[PipelineFull.DescriptorSetLayouts];

            var uDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = uLayoutBindings,
                BindingCount = (uint)uCount
            };

            var sDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = sLayoutBindings,
                BindingCount = (uint)stagesCount
            };

            var tDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = tLayoutBindings,
                BindingCount = (uint)tCount
            };

            var iDescriptorSetLayoutCreateInfo = new DescriptorSetLayoutCreateInfo()
            {
                SType        = StructureType.DescriptorSetLayoutCreateInfo,
                PBindings    = iLayoutBindings,
                BindingCount = (uint)iCount
            };

            gd.Api.CreateDescriptorSetLayout(device, uDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.UniformSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, sDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.StorageSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, tDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.TextureSetIndex]).ThrowOnError();
            gd.Api.CreateDescriptorSetLayout(device, iDescriptorSetLayoutCreateInfo, null, out layouts[PipelineFull.ImageSetIndex]).ThrowOnError();

            fixed(DescriptorSetLayout *pLayouts = layouts)
            {
                var pipelineLayoutCreateInfo = new PipelineLayoutCreateInfo()
                {
                    SType          = StructureType.PipelineLayoutCreateInfo,
                    PSetLayouts    = pLayouts,
                    SetLayoutCount = PipelineFull.DescriptorSetLayouts
                };

                gd.Api.CreatePipelineLayout(device, &pipelineLayoutCreateInfo, null, out layout).ThrowOnError();
            }

            return(layouts);
        }