mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-13 18:28:35 +12:00
vk: Implement descriptor allocation batching
This commit is contained in:
parent
2e22a0d9bb
commit
7c5b5d25e3
3 changed files with 83 additions and 21 deletions
|
@ -1079,18 +1079,7 @@ VkDescriptorSet VKGSRender::allocate_descriptor_set()
|
|||
if (!m_shader_interpreter.is_interpreter(m_program)) [[likely]]
|
||||
{
|
||||
ensure(m_current_frame->used_descriptors < DESCRIPTOR_MAX_DRAW_CALLS);
|
||||
|
||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||
alloc_info.descriptorPool = m_current_frame->descriptor_pool;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &descriptor_layouts;
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
|
||||
VkDescriptorSet new_descriptor_set;
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_device, &alloc_info, &new_descriptor_set));
|
||||
m_current_frame->used_descriptors++;
|
||||
|
||||
return new_descriptor_set;
|
||||
return m_current_frame->descriptor_pool.allocate(descriptor_layouts, VK_TRUE, m_current_frame->used_descriptors++);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -18,6 +18,13 @@ namespace vk
|
|||
|
||||
void notify(descriptor_set* set)
|
||||
{
|
||||
// Rare event, upon creation of a new set tracker.
|
||||
// Check for spurious 'new' events when the aux context is taking over
|
||||
for (const auto& set_ : m_notification_list)
|
||||
{
|
||||
if (set_ == set) return;
|
||||
}
|
||||
|
||||
m_notification_list.push_back(set);
|
||||
rsx_log.error("Now monitoring %u descriptor sets", m_notification_list.size());
|
||||
}
|
||||
|
@ -74,19 +81,18 @@ namespace vk
|
|||
{
|
||||
ensure(subpool_count);
|
||||
|
||||
VkDescriptorPoolCreateInfo infos = {};
|
||||
infos.flags = dev.get_descriptor_indexing_support() ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
|
||||
infos.maxSets = max_sets;
|
||||
infos.poolSizeCount = size_descriptors_count;
|
||||
infos.pPoolSizes = sizes;
|
||||
infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
info.flags = dev.get_descriptor_indexing_support() ? VK_DESCRIPTOR_POOL_CREATE_UPDATE_AFTER_BIND_BIT : 0;
|
||||
info.maxSets = max_sets;
|
||||
info.poolSizeCount = size_descriptors_count;
|
||||
info.pPoolSizes = sizes;
|
||||
info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO;
|
||||
|
||||
m_owner = &dev;
|
||||
m_device_pools.resize(subpool_count);
|
||||
|
||||
for (auto& pool : m_device_pools)
|
||||
{
|
||||
CHECK_RESULT(vkCreateDescriptorPool(dev, &infos, nullptr, &pool));
|
||||
CHECK_RESULT(vkCreateDescriptorPool(dev, &info, nullptr, &pool));
|
||||
}
|
||||
|
||||
m_current_pool_handle = m_device_pools[0];
|
||||
|
@ -117,11 +123,70 @@ namespace vk
|
|||
|
||||
void descriptor_pool::reset(VkDescriptorPoolResetFlags flags)
|
||||
{
|
||||
m_descriptor_set_cache.clear();
|
||||
m_current_pool_index = (m_current_pool_index + 1) % u32(m_device_pools.size());
|
||||
m_current_pool_handle = m_device_pools[m_current_pool_index];
|
||||
CHECK_RESULT(vkResetDescriptorPool(*m_owner, m_current_pool_handle, flags));
|
||||
}
|
||||
|
||||
VkDescriptorSet descriptor_pool::allocate(VkDescriptorSetLayout layout, VkBool32 use_cache, u32 used_count)
|
||||
{
|
||||
if (use_cache)
|
||||
{
|
||||
if (m_descriptor_set_cache.empty())
|
||||
{
|
||||
// For optimal cache utilization, each pool should only allocate one layout
|
||||
if (m_cached_layout != layout)
|
||||
{
|
||||
m_cached_layout = layout;
|
||||
m_allocation_request_cache.resize(max_cache_size);
|
||||
|
||||
for (auto& layout_ : m_allocation_request_cache)
|
||||
{
|
||||
layout_ = m_cached_layout;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (m_cached_layout != layout)
|
||||
{
|
||||
use_cache = VK_FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_descriptor_set_cache.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
VkDescriptorSet new_descriptor_set;
|
||||
VkDescriptorSetAllocateInfo alloc_info = {};
|
||||
alloc_info.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO;
|
||||
alloc_info.descriptorPool = m_current_pool_handle;
|
||||
alloc_info.descriptorSetCount = 1;
|
||||
alloc_info.pSetLayouts = &layout;
|
||||
|
||||
if (use_cache)
|
||||
{
|
||||
const auto alloc_size = std::min<u32>(info.maxSets - used_count, max_cache_size);
|
||||
|
||||
ensure(alloc_size);
|
||||
ensure(m_descriptor_set_cache.empty());
|
||||
|
||||
alloc_info.descriptorSetCount = alloc_size;
|
||||
alloc_info.pSetLayouts = m_allocation_request_cache.data();
|
||||
|
||||
m_descriptor_set_cache.resize(alloc_size);
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_owner, &alloc_info, m_descriptor_set_cache.data()));
|
||||
|
||||
new_descriptor_set = m_descriptor_set_cache.pop_back();
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_RESULT(vkAllocateDescriptorSets(*m_owner, &alloc_info, &new_descriptor_set));
|
||||
}
|
||||
|
||||
return new_descriptor_set;
|
||||
}
|
||||
|
||||
descriptor_set::descriptor_set(VkDescriptorSet set)
|
||||
{
|
||||
flush();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "commands.h"
|
||||
#include "device.h"
|
||||
|
||||
#include "Emu/RSX/rsx_utils.h"
|
||||
#include "Emu/RSX/Common/simple_array.hpp"
|
||||
|
||||
namespace vk
|
||||
{
|
||||
|
@ -23,17 +23,25 @@ namespace vk
|
|||
bool valid() const;
|
||||
operator VkDescriptorPool();
|
||||
|
||||
VkDescriptorSet allocate(VkDescriptorSetLayout layout, VkBool32 use_cache, u32 used_count);
|
||||
|
||||
private:
|
||||
const vk::render_device* m_owner = nullptr;
|
||||
VkDescriptorPoolCreateInfo info = {};
|
||||
|
||||
rsx::simple_array<VkDescriptorPool> m_device_pools;
|
||||
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
|
||||
u32 m_current_pool_index = 0;
|
||||
|
||||
static const size_t max_cache_size = 64;
|
||||
VkDescriptorSetLayout m_cached_layout = VK_NULL_HANDLE;
|
||||
rsx::simple_array<VkDescriptorSet> m_descriptor_set_cache;
|
||||
rsx::simple_array<VkDescriptorSetLayout> m_allocation_request_cache;
|
||||
};
|
||||
|
||||
class descriptor_set
|
||||
{
|
||||
const size_t max_cache_size = 16384;
|
||||
static const size_t max_cache_size = 16384;
|
||||
void init(VkDescriptorSet new_set);
|
||||
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue