public VkResourceCache(VkDevice device, VkSamplerState defaultSamplerState) { _device = device; _defaultSamplerState = defaultSamplerState; VkDescriptorPoolSize *sizes = stackalloc VkDescriptorPoolSize[3]; sizes[0].type = VkDescriptorType.UniformBuffer; sizes[0].descriptorCount = 50000; sizes[1].type = VkDescriptorType.SampledImage; sizes[1].descriptorCount = 15000; sizes[2].type = VkDescriptorType.Sampler; sizes[2].descriptorCount = 15000; VkDescriptorPoolCreateInfo descriptorPoolCI = VkDescriptorPoolCreateInfo.New(); descriptorPoolCI.flags = VkDescriptorPoolCreateFlags.FreeDescriptorSet; descriptorPoolCI.maxSets = 15000; descriptorPoolCI.pPoolSizes = sizes; descriptorPoolCI.poolSizeCount = 3; VkResult result = vkCreateDescriptorPool(_device, ref descriptorPoolCI, null, out _descriptorPool); CheckResult(result); }
private VkDescriptorSet CreateNewDescriptorSet(ref VkDescriptorSetCacheKey cacheKey) { { VkDescriptorSetAllocateInfo descriptorSetAI = VkDescriptorSetAllocateInfo.New(); descriptorSetAI.descriptorPool = _descriptorPool; descriptorSetAI.descriptorSetCount = 1; VkDescriptorSetLayout layout = cacheKey.ShaderResourceBindingSlots.DescriptorSetLayout; descriptorSetAI.pSetLayouts = &layout; VkResult result = vkAllocateDescriptorSets(_device, ref descriptorSetAI, out VkDescriptorSet descriptorSet); CheckResult(result); int resourceCount = cacheKey.ShaderResourceBindingSlots.Resources.Length; VkWriteDescriptorSet[] descriptorWrites = new VkWriteDescriptorSet[resourceCount]; VkDescriptorBufferInfo *bufferInfos = stackalloc VkDescriptorBufferInfo[resourceCount]; // TODO: Fix this. VkDescriptorImageInfo * imageInfos = stackalloc VkDescriptorImageInfo[resourceCount]; // TODO: Fix this. for (uint binding = 0; binding < resourceCount; binding++) { descriptorWrites[binding].sType = VkStructureType.WriteDescriptorSet; descriptorWrites[binding].descriptorCount = 1; descriptorWrites[binding].dstBinding = binding; descriptorWrites[binding].dstSet = descriptorSet; ShaderResourceDescription resource = cacheKey.ShaderResourceBindingSlots.Resources[binding]; switch (resource.Type) { case ShaderResourceType.ConstantBuffer: { descriptorWrites[binding].descriptorType = VkDescriptorType.UniformBuffer; VkConstantBuffer cb = cacheKey.ConstantBuffers[binding]; if (cb == null) { throw new VeldridException($"No constant buffer bound to required binding slot {binding}."); } VkDescriptorBufferInfo *cbInfo = &bufferInfos[binding]; cbInfo->buffer = cb.DeviceBuffer; cbInfo->offset = 0; cbInfo->range = (ulong)resource.DataSizeInBytes; descriptorWrites[binding].pBufferInfo = cbInfo; break; } case ShaderResourceType.Texture: { descriptorWrites[binding].descriptorType = VkDescriptorType.SampledImage; VkShaderTextureBinding textureBinding = cacheKey.TextureBindings[binding]; if (textureBinding == null) { throw new VeldridException($"No texture bound to required binding slot {binding}."); } VkDescriptorImageInfo *imageInfo = &imageInfos[binding]; imageInfo->imageLayout = textureBinding.ImageLayout; imageInfo->imageView = textureBinding.ImageView; descriptorWrites[binding].pImageInfo = imageInfo; } break; case ShaderResourceType.Sampler: { descriptorWrites[binding].descriptorType = VkDescriptorType.Sampler; VkSamplerState samplerState = cacheKey.SamplerStates[binding] ?? (VkSamplerState)_defaultSamplerState; VkDescriptorImageInfo *imageInfo = &imageInfos[binding]; imageInfo->sampler = samplerState.Sampler; descriptorWrites[binding].pImageInfo = imageInfo; } break; default: throw Illegal.Value <ShaderResourceType>(); } } vkUpdateDescriptorSets(_device, (uint)resourceCount, ref descriptorWrites[0], 0, null); return(descriptorSet); } }