Skip to content

Commit

Permalink
[dxvk] Adjust desciptor pool reset heuristic
Browse files Browse the repository at this point in the history
Drastically limits the amount of descriptor memory we allocate in situations
where an application renders without presenting anything to a swap chain.

The new limit is a bit tight for some real-world use cases (e.g. Ashes of the Singularity),
but at worst we will start calling vkAllocateDescriptorSets once per set and draw.
  • Loading branch information
doitsujin committed Apr 8, 2024
1 parent 49e9ea5 commit 44695f9
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 17 deletions.
23 changes: 9 additions & 14 deletions src/dxvk/dxvk_descriptor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ namespace dxvk {
// memory bloat. This may be necessary for off-screen
// rendering applications, or in situations where games
// pre-render a lot of images without presenting in between.
return m_descriptorPools.size() >= 8;
return m_descriptorPools.size() > MaxDesiredPoolCount;
}


Expand Down Expand Up @@ -100,29 +100,25 @@ namespace dxvk {


void DxvkDescriptorPool::reset() {
// As a heuristic to save memory, check how many descriptors
// have actively been used in the past couple of submissions.
bool isLowUsageFrame = false;

// As a heuristic to save memory, check how many descriptor
// sets were actually being used in past submissions.
size_t poolCount = m_descriptorPools.size();
bool needsReset = poolCount > MaxDesiredPoolCount;

if (poolCount > 1 || m_setsAllocated > m_manager->getMaxSetCount() / 2) {
double factor = std::max(11.0 / 3.0 - double(poolCount) / 3.0, 1.0);
isLowUsageFrame = double(m_setsUsed) * factor < double(m_setsAllocated);
needsReset = double(m_setsUsed) * factor < double(m_setsAllocated);
}

m_lowUsageFrames = isLowUsageFrame
? m_lowUsageFrames + 1
: 0;
m_setsUsed = 0;

if (m_lowUsageFrames < 16) {
if (!needsReset) {
for (auto& entry : m_setLists)
entry.second.reset();
} else {
// 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.
// If most sets are no longer needed, reset and destroy
// descriptor pools and reset all lookup tables in order
// to accomodate more descriptors of different layouts.
for (auto pool : m_descriptorPools)
m_manager->recycleVulkanDescriptorPool(pool);

Expand All @@ -131,7 +127,6 @@ namespace dxvk {
m_setMaps.clear();

m_setsAllocated = 0;
m_lowUsageFrames = 0;
}

m_cachedEntry = { nullptr, nullptr };
Expand Down
4 changes: 1 addition & 3 deletions src/dxvk/dxvk_descriptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ namespace dxvk {
* to be updated.
*/
class DxvkDescriptorPool : public RcObject {

constexpr static uint32_t MaxDesiredPoolCount = 2;
public:

DxvkDescriptorPool(
Expand Down Expand Up @@ -155,8 +155,6 @@ namespace dxvk {

uint32_t m_prevSetsAllocated = 0;

uint32_t m_lowUsageFrames = 0;

DxvkDescriptorSetMap* getSetMapCached(
const DxvkBindingLayoutObjects* layout);

Expand Down

0 comments on commit 44695f9

Please sign in to comment.