vk_descriptor_manager: Cache descriptor sets

This commit is contained in:
GPUCode
2023-03-03 23:06:16 +02:00
parent 39edca2cf7
commit 32cb44d2b9
3 changed files with 33 additions and 16 deletions

View File

@@ -115,18 +115,21 @@ void DescriptorManager::BindDescriptorSets() {
} }
const vk::Device device = instance.GetDevice(); const vk::Device device = instance.GetDevice();
std::array<vk::DescriptorSet, MAX_DESCRIPTOR_SETS> bound_sets;
for (u32 i = 0; i < MAX_DESCRIPTOR_SETS; i++) { for (u32 i = 0; i < MAX_DESCRIPTOR_SETS; i++) {
if (descriptor_set_dirty[i] || is_dirty) { if (descriptor_set_dirty[i] || is_dirty) {
vk::DescriptorSet set = AllocateSet(descriptor_set_layouts[i]); std::vector<vk::DescriptorSet>& cache = set_cache[i];
if (cache.empty()) {
cache = AllocateSets(descriptor_set_layouts[i], MAX_BATCH_SIZE);
}
vk::DescriptorSet set = cache.back();
cache.pop_back();
device.updateDescriptorSetWithTemplate(set, update_templates[i], update_data[i][0]); device.updateDescriptorSetWithTemplate(set, update_templates[i], update_data[i][0]);
descriptor_sets[i] = set; descriptor_sets[i] = set;
} }
bound_sets[i] = descriptor_sets[i];
} }
scheduler.Record([this, bound_sets](vk::CommandBuffer cmdbuf) { scheduler.Record([this, bound_sets = descriptor_sets](vk::CommandBuffer cmdbuf) {
cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, bound_sets, cmdbuf.bindDescriptorSets(vk::PipelineBindPoint::eGraphics, pipeline_layout, 0, bound_sets,
{}); {});
}); });
@@ -185,22 +188,29 @@ void DescriptorManager::BuildLayouts() {
pipeline_layout = device.createPipelineLayout(layout_info); pipeline_layout = device.createPipelineLayout(layout_info);
} }
vk::DescriptorSet DescriptorManager::AllocateSet(vk::DescriptorSetLayout layout) { std::vector<vk::DescriptorSet> DescriptorManager::AllocateSets(vk::DescriptorSetLayout layout, u32 num_sets) {
const vk::Device device = instance.GetDevice(); static std::array<vk::DescriptorSetLayout, MAX_BATCH_SIZE> layouts;
const vk::DescriptorSetAllocateInfo alloc_info = { layouts.fill(layout);
vk::DescriptorSetAllocateInfo alloc_info = {
.descriptorPool = current_pool, .descriptorPool = current_pool,
.descriptorSetCount = 1, .descriptorSetCount = num_sets,
.pSetLayouts = &layout, .pSetLayouts = layouts.data(),
}; };
try { try {
return device.allocateDescriptorSets(alloc_info)[0]; return instance.GetDevice().allocateDescriptorSets(alloc_info);
} catch (vk::OutOfPoolMemoryError) { } catch (vk::OutOfPoolMemoryError) {
pool_provider.RefreshTick(); pool_provider.RefreshTick();
current_pool = pool_provider.Commit(); current_pool = pool_provider.Commit();
for (auto& cache : set_cache) {
cache.clear();
}
descriptor_set_dirty.set();
} }
return AllocateSet(layout); alloc_info.descriptorPool = current_pool;
return instance.GetDevice().allocateDescriptorSets(alloc_info);
} }
} // namespace Vulkan } // namespace Vulkan

View File

@@ -11,6 +11,7 @@ namespace Vulkan {
constexpr u32 MAX_DESCRIPTORS = 7; constexpr u32 MAX_DESCRIPTORS = 7;
constexpr u32 MAX_DESCRIPTOR_SETS = 3; constexpr u32 MAX_DESCRIPTOR_SETS = 3;
constexpr u32 MAX_BATCH_SIZE = 32;
union DescriptorData { union DescriptorData {
vk::DescriptorImageInfo image_info; vk::DescriptorImageInfo image_info;
@@ -32,8 +33,13 @@ public:
DescriptorManager(const Instance& instance, Scheduler& scheduler); DescriptorManager(const Instance& instance, Scheduler& scheduler);
~DescriptorManager(); ~DescriptorManager();
/// Allocates an array of descriptor sets of the provided layout
std::vector<vk::DescriptorSet> AllocateSets(vk::DescriptorSetLayout layout, u32 num_sets);
/// Allocates a descriptor set of the provided layout /// Allocates a descriptor set of the provided layout
vk::DescriptorSet AllocateSet(vk::DescriptorSetLayout layout); vk::DescriptorSet AllocateSet(vk::DescriptorSetLayout layout) {
return AllocateSets(layout, 1)[0];
}
/// Binds a resource to the provided binding /// Binds a resource to the provided binding
void SetBinding(u32 set, u32 binding, DescriptorData data); void SetBinding(u32 set, u32 binding, DescriptorData data);
@@ -60,6 +66,7 @@ private:
std::array<vk::DescriptorUpdateTemplate, MAX_DESCRIPTOR_SETS> update_templates; std::array<vk::DescriptorUpdateTemplate, MAX_DESCRIPTOR_SETS> update_templates;
std::array<DescriptorSetData, MAX_DESCRIPTOR_SETS> update_data{}; std::array<DescriptorSetData, MAX_DESCRIPTOR_SETS> update_data{};
std::array<vk::DescriptorSet, MAX_DESCRIPTOR_SETS> descriptor_sets{}; std::array<vk::DescriptorSet, MAX_DESCRIPTOR_SETS> descriptor_sets{};
std::array<std::vector<vk::DescriptorSet>, MAX_DESCRIPTOR_SETS> set_cache;
std::bitset<MAX_DESCRIPTOR_SETS> descriptor_set_dirty{}; std::bitset<MAX_DESCRIPTOR_SETS> descriptor_set_dirty{};
}; };

View File

@@ -129,9 +129,9 @@ void DescriptorPool::Allocate(std::size_t begin, std::size_t end) {
// Choose a sane pool size good for most games // Choose a sane pool size good for most games
static constexpr std::array<vk::DescriptorPoolSize, 4> pool_sizes = {{ static constexpr std::array<vk::DescriptorPoolSize, 4> pool_sizes = {{
{vk::DescriptorType::eUniformBuffer, 1024}, {vk::DescriptorType::eUniformBuffer, 4096},
{vk::DescriptorType::eCombinedImageSampler, 2048}, {vk::DescriptorType::eCombinedImageSampler, 8192},
{vk::DescriptorType::eUniformTexelBuffer, 1024}, {vk::DescriptorType::eUniformTexelBuffer, 4096},
{vk::DescriptorType::eStorageImage, 1024}, {vk::DescriptorType::eStorageImage, 1024},
}}; }};