diff --git a/src/video_core/renderer_vulkan/vk_descriptor_manager.cpp b/src/video_core/renderer_vulkan/vk_descriptor_manager.cpp index 3041859c7..9a234c5d0 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_manager.cpp +++ b/src/video_core/renderer_vulkan/vk_descriptor_manager.cpp @@ -115,18 +115,21 @@ void DescriptorManager::BindDescriptorSets() { } const vk::Device device = instance.GetDevice(); - std::array bound_sets; for (u32 i = 0; i < MAX_DESCRIPTOR_SETS; i++) { if (descriptor_set_dirty[i] || is_dirty) { - vk::DescriptorSet set = AllocateSet(descriptor_set_layouts[i]); + std::vector& 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]); 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, {}); }); @@ -185,22 +188,29 @@ void DescriptorManager::BuildLayouts() { pipeline_layout = device.createPipelineLayout(layout_info); } -vk::DescriptorSet DescriptorManager::AllocateSet(vk::DescriptorSetLayout layout) { - const vk::Device device = instance.GetDevice(); - const vk::DescriptorSetAllocateInfo alloc_info = { +std::vector DescriptorManager::AllocateSets(vk::DescriptorSetLayout layout, u32 num_sets) { + static std::array layouts; + layouts.fill(layout); + + vk::DescriptorSetAllocateInfo alloc_info = { .descriptorPool = current_pool, - .descriptorSetCount = 1, - .pSetLayouts = &layout, + .descriptorSetCount = num_sets, + .pSetLayouts = layouts.data(), }; try { - return device.allocateDescriptorSets(alloc_info)[0]; + return instance.GetDevice().allocateDescriptorSets(alloc_info); } catch (vk::OutOfPoolMemoryError) { pool_provider.RefreshTick(); 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 diff --git a/src/video_core/renderer_vulkan/vk_descriptor_manager.h b/src/video_core/renderer_vulkan/vk_descriptor_manager.h index 2a3564879..0d41ae55d 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_manager.h +++ b/src/video_core/renderer_vulkan/vk_descriptor_manager.h @@ -11,6 +11,7 @@ namespace Vulkan { constexpr u32 MAX_DESCRIPTORS = 7; constexpr u32 MAX_DESCRIPTOR_SETS = 3; +constexpr u32 MAX_BATCH_SIZE = 32; union DescriptorData { vk::DescriptorImageInfo image_info; @@ -32,8 +33,13 @@ public: DescriptorManager(const Instance& instance, Scheduler& scheduler); ~DescriptorManager(); + /// Allocates an array of descriptor sets of the provided layout + std::vector AllocateSets(vk::DescriptorSetLayout layout, u32 num_sets); + /// 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 void SetBinding(u32 set, u32 binding, DescriptorData data); @@ -60,6 +66,7 @@ private: std::array update_templates; std::array update_data{}; std::array descriptor_sets{}; + std::array, MAX_DESCRIPTOR_SETS> set_cache; std::bitset descriptor_set_dirty{}; }; diff --git a/src/video_core/renderer_vulkan/vk_resource_pool.cpp b/src/video_core/renderer_vulkan/vk_resource_pool.cpp index 11308d544..434ea354c 100644 --- a/src/video_core/renderer_vulkan/vk_resource_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_resource_pool.cpp @@ -129,9 +129,9 @@ void DescriptorPool::Allocate(std::size_t begin, std::size_t end) { // Choose a sane pool size good for most games static constexpr std::array pool_sizes = {{ - {vk::DescriptorType::eUniformBuffer, 1024}, - {vk::DescriptorType::eCombinedImageSampler, 2048}, - {vk::DescriptorType::eUniformTexelBuffer, 1024}, + {vk::DescriptorType::eUniformBuffer, 4096}, + {vk::DescriptorType::eCombinedImageSampler, 8192}, + {vk::DescriptorType::eUniformTexelBuffer, 4096}, {vk::DescriptorType::eStorageImage, 1024}, }};