public DescriptorSetLayoutCreateInfo ( StructureType?sType = StructureType.DescriptorSetLayoutCreateInfo, void *pNext = null, DescriptorSetLayoutCreateFlags?flags = null, uint?bindingCount = null, DescriptorSetLayoutBinding *pBindings = null ) : this() { if (sType is not null) { SType = sType.Value; } if (pNext is not null) { PNext = pNext; } if (flags is not null) { Flags = flags.Value; } if (bindingCount is not null) { BindingCount = bindingCount.Value; } if (pBindings is not null) { PBindings = pBindings; } }
public unsafe void CreateLayout() { Device device = _renderer.Params.Device; AllocationCallbacks *allocator = (AllocationCallbacks *)_renderer.Params.AllocationCallbacks.ToPointer(); Vk vk = _renderer.Vk; DescriptorSetLayoutBinding *descriptorSetLayoutBindings = stackalloc DescriptorSetLayoutBinding[] { new DescriptorSetLayoutBinding() // vertex binding { Binding = 0, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, PImmutableSamplers = null, StageFlags = ShaderStageFlags.ShaderStageVertexBit }, new DescriptorSetLayoutBinding() // fragment binding { Binding = 1, DescriptorCount = 1, DescriptorType = DescriptorType.UniformBuffer, PImmutableSamplers = null, StageFlags = ShaderStageFlags.ShaderStageFragmentBit }, new DescriptorSetLayoutBinding() // image sampler(2D) { Binding = 2, DescriptorCount = 1, DescriptorType = DescriptorType.CombinedImageSampler, PImmutableSamplers = null, StageFlags = ShaderStageFlags.ShaderStageFragmentBit } }; DescriptorSetLayoutCreateInfo descriptorSetLayoutCreateInfo = new() { SType = StructureType.DescriptorSetLayoutCreateInfo, BindingCount = 3, // FIXME: 3 - vertex, fragment and image PBindings = descriptorSetLayoutBindings }; _renderer.AssertVulkan(vk.CreateDescriptorSetLayout(device, descriptorSetLayoutCreateInfo, allocator, out _descriptorSetLayout)); PipelineLayoutCreateInfo pipelineLayoutCreateInfo = new() { SType = StructureType.PipelineLayoutCreateInfo, PushConstantRangeCount = 0, PPushConstantRanges = null, SetLayoutCount = 1, }; fixed(DescriptorSetLayout *ptr = &_descriptorSetLayout) { pipelineLayoutCreateInfo.PSetLayouts = ptr; } _renderer.AssertVulkan(vk.CreatePipelineLayout(device, pipelineLayoutCreateInfo, allocator, out _pipelineLayout)); }
protected override unsafe DescriptorSetLayout[] CreateDescriptorSetLayouts(VulkanGraphicsDevice gd, Device device, out PipelineLayout layout) { DescriptorSetLayoutBinding *uLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxUniformBufferBindings]; DescriptorSetLayoutBinding *sLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxStorageBufferBindings]; DescriptorSetLayoutBinding *tLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings]; DescriptorSetLayoutBinding *iLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings]; DescriptorSetLayoutBinding *bTLayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxTextureBindings]; DescriptorSetLayoutBinding *bILayoutBindings = stackalloc DescriptorSetLayoutBinding[Constants.MaxImageBindings]; DescriptorBindingFlags *pUBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxUniformBufferBindings]; DescriptorBindingFlags *pSBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxStorageBufferBindings]; DescriptorBindingFlags *pTBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings]; DescriptorBindingFlags *pIBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings]; DescriptorBindingFlags *pBTBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxTextureBindings]; DescriptorBindingFlags *pBIBindingsFlags = stackalloc DescriptorBindingFlags[Constants.MaxImageBindings];
public DescriptorSetLayoutCreateInfo ( StructureType sType = StructureType.DescriptorSetLayoutCreateInfo, void *pNext = default, DescriptorSetLayoutCreateFlags flags = default, uint bindingCount = default, DescriptorSetLayoutBinding *pBindings = default ) { SType = sType; PNext = pNext; Flags = flags; BindingCount = bindingCount; PBindings = pBindings; }
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); } }
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); }