public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description) : base(ref description) { _gd = gd; VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout); VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout; _descriptorCounts = vkLayout.DescriptorResourceCounts; _descriptorAllocationToken = _gd.DescriptorPoolManager.Allocate(_descriptorCounts, dsl); BindableResource[] boundResources = description.BoundResources; uint descriptorWriteCount = (uint)boundResources.Length; VkWriteDescriptorSet * descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount]; VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount]; for (int i = 0; i < descriptorWriteCount; i++) { VkDescriptorType type = vkLayout.DescriptorTypes[i]; descriptorWrites[i].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[i].descriptorCount = 1; descriptorWrites[i].descriptorType = type; descriptorWrites[i].dstBinding = (uint)i; descriptorWrites[i].dstSet = _descriptorAllocationToken.Set; if (type == VkDescriptorType.UniformBuffer || type == VkDescriptorType.StorageBuffer) { VkBuffer vkBuffer = Util.AssertSubtype <BindableResource, VkBuffer>(boundResources[i]); bufferInfos[i].buffer = vkBuffer.DeviceBuffer; bufferInfos[i].range = vkBuffer.SizeInBytes; descriptorWrites[i].pBufferInfo = &bufferInfos[i]; } else if (type == VkDescriptorType.SampledImage) { VkTextureView textureView = Util.AssertSubtype <BindableResource, VkTextureView>(boundResources[i]); imageInfos[i].imageView = textureView.ImageView; imageInfos[i].imageLayout = VkImageLayout.ShaderReadOnlyOptimal; descriptorWrites[i].pImageInfo = &imageInfos[i]; } else if (type == VkDescriptorType.StorageImage) { VkTextureView textureView = Util.AssertSubtype <BindableResource, VkTextureView>(boundResources[i]); imageInfos[i].imageView = textureView.ImageView; imageInfos[i].imageLayout = VkImageLayout.General; descriptorWrites[i].pImageInfo = &imageInfos[i]; } else if (type == VkDescriptorType.Sampler) { VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]); imageInfos[i].sampler = sampler.DeviceSampler; descriptorWrites[i].pImageInfo = &imageInfos[i]; } } vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null); }
public PoolInfo(VkDescriptorPool pool, uint totalSets, DescriptorResourceCounts counts) { Pool = pool; RemainingSets = totalSets; UniformBufferCount = counts.UniformBufferCount; SampledImageCount = counts.SampledImageCount; SamplerCount = counts.SamplerCount; StorageBufferCount = counts.StorageBufferCount; StorageImageCount = counts.StorageImageCount; }
public void Free(DescriptorAllocationToken token, DescriptorResourceCounts counts) { lock (_lock) { foreach (PoolInfo poolInfo in _pools) { if (poolInfo.Pool == token.Pool) { poolInfo.Free(_gd.Device, token, counts); } } } }
internal void Free(VkDevice device, DescriptorAllocationToken token, DescriptorResourceCounts counts) { VkDescriptorSet set = token.Set; vkFreeDescriptorSets(device, Pool, 1, ref set); RemainingSets += 1; UniformBufferCount += counts.UniformBufferCount; SampledImageCount += counts.SampledImageCount; SamplerCount += counts.SamplerCount; StorageBufferCount += counts.StorageBufferCount; StorageImageCount += counts.StorageImageCount; }
public unsafe DescriptorAllocationToken Allocate(DescriptorResourceCounts counts, VkDescriptorSetLayout setLayout) { VkDescriptorPool pool = GetPool(counts); VkDescriptorSetAllocateInfo dsAI = VkDescriptorSetAllocateInfo.New(); dsAI.descriptorSetCount = 1; dsAI.pSetLayouts = &setLayout; dsAI.descriptorPool = pool; VkResult result = vkAllocateDescriptorSets(_gd.Device, ref dsAI, out VkDescriptorSet set); VulkanUtil.CheckResult(result); return(new DescriptorAllocationToken(set, pool)); }
private VkDescriptorPool GetPool(DescriptorResourceCounts counts) { lock (_lock) { foreach (PoolInfo poolInfo in _pools) { if (poolInfo.Allocate(counts)) { return(poolInfo.Pool); } } PoolInfo newPool = CreateNewPool(); _pools.Add(newPool); bool result = newPool.Allocate(counts); Debug.Assert(result); return(newPool.Pool); } }
private unsafe PoolInfo CreateNewPool(DescriptorResourceCounts counts) { uint totalSets = 1000; uint descriptorCount = 100; uint poolSizeCount = 7; VkDescriptorPoolSize *sizes = stackalloc VkDescriptorPoolSize[(int)poolSizeCount]; sizes[0].type = VkDescriptorType.UniformBuffer; sizes[0].descriptorCount = counts.UniformBufferCount < descriptorCount ? descriptorCount : counts.UniformBufferCount; sizes[1].type = VkDescriptorType.SampledImage; sizes[1].descriptorCount = counts.SampledImageCount < descriptorCount ? descriptorCount : counts.SampledImageCount; sizes[2].type = VkDescriptorType.Sampler; sizes[2].descriptorCount = counts.SamplerCount < descriptorCount ? descriptorCount : counts.SamplerCount; sizes[3].type = VkDescriptorType.StorageBuffer; sizes[3].descriptorCount = counts.StorageBufferCount < descriptorCount ? descriptorCount : counts.StorageBufferCount; sizes[4].type = VkDescriptorType.StorageImage; sizes[4].descriptorCount = counts.StorageImageCount < descriptorCount ? descriptorCount : counts.StorageImageCount; sizes[5].type = VkDescriptorType.UniformBufferDynamic; sizes[5].descriptorCount = descriptorCount; sizes[6].type = VkDescriptorType.StorageBufferDynamic; sizes[6].descriptorCount = descriptorCount; VkDescriptorPoolCreateInfo poolCI = VkDescriptorPoolCreateInfo.New(); poolCI.flags = VkDescriptorPoolCreateFlags.FreeDescriptorSet; poolCI.maxSets = totalSets; poolCI.pPoolSizes = sizes; poolCI.poolSizeCount = poolSizeCount; VkResult result = vkCreateDescriptorPool(_gd.Device, ref poolCI, null, out VkDescriptorPool descriptorPool); VulkanUtil.CheckResult(result); DescriptorResourceCounts cts = new DescriptorResourceCounts( counts.UniformBufferCount < descriptorCount ? descriptorCount : counts.UniformBufferCount, counts.SampledImageCount < descriptorCount ? descriptorCount : counts.SampledImageCount, counts.SamplerCount < descriptorCount ? descriptorCount : counts.SamplerCount, counts.StorageBufferCount < descriptorCount ? descriptorCount : counts.StorageBufferCount, counts.StorageImageCount < descriptorCount ? descriptorCount : counts.StorageImageCount); return(new PoolInfo(descriptorPool, totalSets, cts)); }
internal bool Allocate(DescriptorResourceCounts counts) { if (RemainingSets > 0 && UniformBufferCount >= counts.UniformBufferCount && SampledImageCount >= counts.SampledImageCount && SamplerCount >= counts.SamplerCount && StorageBufferCount >= counts.SamplerCount && StorageImageCount >= counts.StorageImageCount) { RemainingSets -= 1; UniformBufferCount -= counts.UniformBufferCount; SampledImageCount -= counts.SampledImageCount; SamplerCount -= counts.SamplerCount; StorageBufferCount -= counts.StorageBufferCount; StorageImageCount -= counts.StorageImageCount; return(true); } else { return(false); } }
public VkResourceSet(VkGraphicsDevice gd, ref ResourceSetDescription description) : base(ref description) { _gd = gd; RefCount = new ResourceRefCount(DisposeCore); VkResourceLayout vkLayout = Util.AssertSubtype <ResourceLayout, VkResourceLayout>(description.Layout); VkDescriptorSetLayout dsl = vkLayout.DescriptorSetLayout; _descriptorCounts = vkLayout.DescriptorResourceCounts; _descriptorAllocationToken = _gd.DescriptorPoolManager.Allocate(_descriptorCounts, dsl); BindableResource[] boundResources = description.BoundResources; uint descriptorWriteCount = (uint)boundResources.Length; VkWriteDescriptorSet * descriptorWrites = stackalloc VkWriteDescriptorSet[(int)descriptorWriteCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[(int)descriptorWriteCount]; VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[(int)descriptorWriteCount]; for (int i = 0; i < descriptorWriteCount; i++) { VkDescriptorType type = vkLayout.DescriptorTypes[i]; descriptorWrites[i].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[i].descriptorCount = 1; descriptorWrites[i].descriptorType = type; descriptorWrites[i].dstBinding = (uint)i; descriptorWrites[i].dstSet = _descriptorAllocationToken.Set; if (type == VkDescriptorType.UniformBuffer || type == VkDescriptorType.UniformBufferDynamic || type == VkDescriptorType.StorageBuffer || type == VkDescriptorType.StorageBufferDynamic) { DeviceBufferRange range = Util.GetBufferRange(boundResources[i], 0); VkBuffer rangedVkBuffer = Util.AssertSubtype <DeviceBuffer, VkBuffer>(range.Buffer); bufferInfos[i].buffer = rangedVkBuffer.DeviceBuffer; bufferInfos[i].offset = range.Offset; bufferInfos[i].range = range.SizeInBytes; descriptorWrites[i].pBufferInfo = &bufferInfos[i]; _refCounts.Add(rangedVkBuffer.RefCount); } else if (type == VkDescriptorType.SampledImage) { TextureView texView = Util.GetTextureView(_gd, boundResources[i]); VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView); imageInfos[i].imageView = vkTexView.ImageView; imageInfos[i].imageLayout = VkImageLayout.ShaderReadOnlyOptimal; descriptorWrites[i].pImageInfo = &imageInfos[i]; _sampledTextures.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target)); _refCounts.Add(vkTexView.RefCount); } else if (type == VkDescriptorType.StorageImage) { TextureView texView = Util.GetTextureView(_gd, boundResources[i]); VkTextureView vkTexView = Util.AssertSubtype <TextureView, VkTextureView>(texView); imageInfos[i].imageView = vkTexView.ImageView; imageInfos[i].imageLayout = VkImageLayout.General; descriptorWrites[i].pImageInfo = &imageInfos[i]; _storageImages.Add(Util.AssertSubtype <Texture, VkTexture>(texView.Target)); _refCounts.Add(vkTexView.RefCount); } else if (type == VkDescriptorType.Sampler) { VkSampler sampler = Util.AssertSubtype <BindableResource, VkSampler>(boundResources[i]); imageInfos[i].sampler = sampler.DeviceSampler; descriptorWrites[i].pImageInfo = &imageInfos[i]; _refCounts.Add(sampler.RefCount); } } vkUpdateDescriptorSets(_gd.Device, descriptorWriteCount, descriptorWrites, 0, null); }
public VkResourceLayout(VkGraphicsDevice gd, ref ResourceLayoutDescription description) : base(ref description) { _gd = gd; VkDescriptorSetLayoutCreateInfo dslCI = VkDescriptorSetLayoutCreateInfo.New(); ResourceLayoutElementDescription[] elements = description.Elements; _descriptorTypes = new VkDescriptorType[elements.Length]; VkDescriptorSetLayoutBinding *bindings = stackalloc VkDescriptorSetLayoutBinding[elements.Length]; uint uniformBufferCount = 0; uint sampledImageCount = 0; uint samplerCount = 0; uint storageBufferCount = 0; uint storageImageCount = 0; for (uint i = 0; i < elements.Length; i++) { bindings[i].binding = i; bindings[i].descriptorCount = 1; VkDescriptorType descriptorType = VkFormats.VdToVkDescriptorType(elements[i].Kind, elements[i].Options); bindings[i].descriptorType = descriptorType; bindings[i].stageFlags = VkFormats.VdToVkShaderStages(elements[i].Stages); if ((elements[i].Options & ResourceLayoutElementOptions.DynamicBinding) != 0) { DynamicBufferCount += 1; } _descriptorTypes[i] = descriptorType; switch (descriptorType) { case VkDescriptorType.Sampler: samplerCount += 1; break; case VkDescriptorType.SampledImage: sampledImageCount += 1; break; case VkDescriptorType.StorageImage: storageImageCount += 1; break; case VkDescriptorType.UniformBuffer: uniformBufferCount += 1; break; case VkDescriptorType.StorageBuffer: storageBufferCount += 1; break; } } DescriptorResourceCounts = new DescriptorResourceCounts( uniformBufferCount, sampledImageCount, samplerCount, storageBufferCount, storageImageCount); dslCI.bindingCount = (uint)elements.Length; dslCI.pBindings = bindings; VkResult result = vkCreateDescriptorSetLayout(_gd.Device, ref dslCI, null, out _dsl); CheckResult(result); }