mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-31 14:52:11 +01:00
[dxvk] Recycle Vulkan descriptor pools as well
Reduces the number of expensive reallocations when large descriptor pools get reset and repopulated.
This commit is contained in:
parent
eea5c9f0da
commit
cfc06405d2
@ -35,8 +35,8 @@ namespace dxvk {
|
||||
|
||||
DxvkDescriptorPool::DxvkDescriptorPool(
|
||||
DxvkDevice* device,
|
||||
DxvkContextType contextType)
|
||||
: m_device(device), m_contextType(contextType),
|
||||
DxvkDescriptorManager* manager)
|
||||
: m_device(device), m_manager(manager),
|
||||
m_cachedEntry(nullptr, nullptr) {
|
||||
|
||||
}
|
||||
@ -100,13 +100,10 @@ namespace dxvk {
|
||||
// If most sets are no longer being used, reset and destroy
|
||||
// descriptor pools and reset all lookup tables in order to
|
||||
// accomodate more descriptors of different layouts.
|
||||
auto vk = m_device->vkd();
|
||||
vk->vkResetDescriptorPool(vk->device(), m_descriptorPools[0], 0);
|
||||
for (auto pool : m_descriptorPools)
|
||||
m_manager->recycleVulkanDescriptorPool(pool);
|
||||
|
||||
for (uint32_t i = 1; i < m_descriptorPools.size(); i++)
|
||||
vk->vkDestroyDescriptorPool(vk->device(), m_descriptorPools[i], nullptr);
|
||||
|
||||
m_descriptorPools.resize(1);
|
||||
m_descriptorPools.clear();
|
||||
m_setLists.clear();
|
||||
m_setMaps.clear();
|
||||
|
||||
@ -205,8 +202,55 @@ namespace dxvk {
|
||||
|
||||
|
||||
VkDescriptorPool DxvkDescriptorPool::addPool() {
|
||||
VkDescriptorPool pool = m_manager->createVulkanDescriptorPool();
|
||||
m_descriptorPools.push_back(pool);
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
DxvkDescriptorManager::DxvkDescriptorManager(
|
||||
DxvkDevice* device,
|
||||
DxvkContextType contextType)
|
||||
: m_device(device), m_contextType(contextType) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
DxvkDescriptorManager::~DxvkDescriptorManager() {
|
||||
auto vk = m_device->vkd();
|
||||
|
||||
for (size_t i = 0; i < m_vkPoolCount; i++)
|
||||
vk->vkDestroyDescriptorPool(vk->device(), m_vkPools[i], nullptr);
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkDescriptorPool> DxvkDescriptorManager::getDescriptorPool() {
|
||||
Rc<DxvkDescriptorPool> pool = m_pools.retrieveObject();
|
||||
|
||||
if (pool == nullptr)
|
||||
pool = new DxvkDescriptorPool(m_device, this);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
void DxvkDescriptorManager::recycleDescriptorPool(
|
||||
const Rc<DxvkDescriptorPool>& pool) {
|
||||
pool->reset();
|
||||
|
||||
m_pools.returnObject(pool);
|
||||
}
|
||||
|
||||
|
||||
VkDescriptorPool DxvkDescriptorManager::createVulkanDescriptorPool() {
|
||||
auto vk = m_device->vkd();
|
||||
|
||||
{ std::lock_guard lock(m_mutex);
|
||||
|
||||
if (m_vkPoolCount)
|
||||
return m_vkPools[--m_vkPoolCount];
|
||||
}
|
||||
|
||||
uint32_t maxSets = m_contextType == DxvkContextType::Primary
|
||||
? 8192 : 256;
|
||||
|
||||
@ -233,39 +277,23 @@ namespace dxvk {
|
||||
if (vk->vkCreateDescriptorPool(vk->device(), &info, nullptr, &pool) != VK_SUCCESS)
|
||||
throw DxvkError("DxvkDescriptorPool: Failed to create descriptor pool");
|
||||
|
||||
m_descriptorPools.push_back(pool);
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
DxvkDescriptorManager::DxvkDescriptorManager(
|
||||
DxvkDevice* device,
|
||||
DxvkContextType contextType)
|
||||
: m_device(device), m_contextType(contextType) {
|
||||
void DxvkDescriptorManager::recycleVulkanDescriptorPool(VkDescriptorPool pool) {
|
||||
auto vk = m_device->vkd();
|
||||
vk->vkResetDescriptorPool(vk->device(), pool, 0);
|
||||
|
||||
}
|
||||
{ std::lock_guard lock(m_mutex);
|
||||
|
||||
if (m_vkPoolCount < m_vkPools.size()) {
|
||||
m_vkPools[m_vkPoolCount++] = pool;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
DxvkDescriptorManager::~DxvkDescriptorManager() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
Rc<DxvkDescriptorPool> DxvkDescriptorManager::getDescriptorPool() {
|
||||
Rc<DxvkDescriptorPool> pool = m_pools.retrieveObject();
|
||||
|
||||
if (pool == nullptr)
|
||||
pool = new DxvkDescriptorPool(m_device, m_contextType);
|
||||
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
||||
void DxvkDescriptorManager::recycleDescriptorPool(
|
||||
const Rc<DxvkDescriptorPool>& pool) {
|
||||
pool->reset();
|
||||
|
||||
m_pools.returnObject(pool);
|
||||
vk->vkDestroyDescriptorPool(vk->device(), pool, nullptr);
|
||||
}
|
||||
|
||||
}
|
@ -9,6 +9,7 @@
|
||||
namespace dxvk {
|
||||
|
||||
class DxvkDevice;
|
||||
class DxvkDescriptorManager;
|
||||
|
||||
/**
|
||||
* \brief DXVK context type
|
||||
@ -83,7 +84,7 @@ namespace dxvk {
|
||||
|
||||
DxvkDescriptorPool(
|
||||
DxvkDevice* device,
|
||||
DxvkContextType contextType);
|
||||
DxvkDescriptorManager* manager);
|
||||
|
||||
~DxvkDescriptorPool();
|
||||
|
||||
@ -116,7 +117,7 @@ namespace dxvk {
|
||||
private:
|
||||
|
||||
DxvkDevice* m_device;
|
||||
DxvkContextType m_contextType;
|
||||
DxvkDescriptorManager* m_manager;
|
||||
|
||||
std::vector<VkDescriptorPool> m_descriptorPools;
|
||||
std::unordered_map<VkDescriptorSetLayout, DxvkDescriptorSetList> m_setLists;
|
||||
@ -176,12 +177,35 @@ namespace dxvk {
|
||||
void recycleDescriptorPool(
|
||||
const Rc<DxvkDescriptorPool>& pool);
|
||||
|
||||
/**
|
||||
* \brief Creates a Vulkan descriptor pool
|
||||
*
|
||||
* Returns an existing unused pool or
|
||||
* creates a new one if necessary.
|
||||
* \returns The descriptor pool
|
||||
*/
|
||||
VkDescriptorPool createVulkanDescriptorPool();
|
||||
|
||||
/**
|
||||
* \brief Returns unused descriptor pool
|
||||
*
|
||||
* Caches the pool for future use, or destroys
|
||||
* it if there are too many objects in the cache
|
||||
* already.
|
||||
* \param [in] pool Vulkan descriptor pool
|
||||
*/
|
||||
void recycleVulkanDescriptorPool(VkDescriptorPool pool);
|
||||
|
||||
private:
|
||||
|
||||
DxvkDevice* m_device;
|
||||
DxvkContextType m_contextType;
|
||||
DxvkRecycler<DxvkDescriptorPool, 8> m_pools;
|
||||
|
||||
dxvk::mutex m_mutex;
|
||||
std::array<VkDescriptorPool, 8> m_vkPools;
|
||||
size_t m_vkPoolCount = 0;
|
||||
|
||||
};
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user