1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-02-20 10:54:16 +01:00

[dxvk] Limit amount of memory to relocate per submission

If the resources we're moving around are in slow memory, moving a full
chunk at once can already take several milliseconds. Try to avoid that.
This commit is contained in:
Philip Rebohle 2024-10-21 23:54:54 +02:00 committed by Philip Rebohle
parent 787671ef62
commit 7a09ab6c83
3 changed files with 37 additions and 12 deletions

View File

@ -6497,8 +6497,13 @@ namespace dxvk {
void DxvkContext::relocateQueuedResources() {
// Limit the number and size of resources to process per submission to
// something reasonable. We don't know if we are transferring over PCIe.
constexpr static uint32_t MaxRelocationsPerSubmission = 128u;
auto resourceList = m_common->memoryManager().pollRelocationList(MaxRelocationsPerSubmission);
constexpr static uint32_t MaxRelocatedMemoryPerSubmission = 16u << 20;
auto resourceList = m_common->memoryManager().pollRelocationList(
MaxRelocationsPerSubmission, MaxRelocatedMemoryPerSubmission);
if (resourceList.empty())
return;

View File

@ -469,7 +469,9 @@ namespace dxvk {
}
std::vector<DxvkRelocationEntry> DxvkRelocationList::poll(uint32_t count) {
std::vector<DxvkRelocationEntry> DxvkRelocationList::poll(
uint32_t count,
VkDeviceSize size) {
std::lock_guard lock(m_mutex);
std::vector<DxvkRelocationEntry> result;
@ -480,10 +482,17 @@ namespace dxvk {
result.reserve(count);
VkDeviceSize totalSize = 0u;
for (uint32_t i = 0; i < count; i++) {
auto iter = m_entries.begin();
result.push_back({ iter->first, iter->second });
if (totalSize && totalSize + iter->second.size > size)
break;
totalSize += iter->second.size;
result.push_back({ iter->first, iter->second.mode });
m_entries.erase(iter);
}
@ -493,9 +502,10 @@ namespace dxvk {
void DxvkRelocationList::addResource(
Rc<DxvkPagedResource>&& resource,
DxvkAllocationModes mode) {
DxvkAllocationModes mode,
VkDeviceSize size) {
std::lock_guard lock(m_mutex);
m_entries.emplace(std::move(resource), mode);
m_entries.emplace(std::move(resource), Entry { mode, size });
}
@ -2110,7 +2120,7 @@ namespace dxvk {
continue;
// Acquired the resource, add it to the relocation list.
m_relocations.addResource(std::move(resource), mode);
m_relocations.addResource(std::move(resource), mode, a->m_size);
}
}

View File

@ -998,20 +998,24 @@ namespace dxvk {
* Removes items from the internally stored list.
* Any duplicate entries will be removed.
* \param [in] count Number of entries to return
* \param [in] size Maximum total resource size
* \returns List of resources to move
*/
std::vector<DxvkRelocationEntry> poll(
uint32_t count);
uint32_t count,
VkDeviceSize size);
/**
* \brief Adds relocation entry to the list
*
* \param [in] resource Resource to add
* \param [in] mode Allocation mode
* \param [in] size Allocation size
*/
void addResource(
Rc<DxvkPagedResource>&& resource,
DxvkAllocationModes mode);
DxvkAllocationModes mode,
VkDeviceSize size);
/**
* \brief Clears list
@ -1028,9 +1032,14 @@ namespace dxvk {
private:
struct Entry {
DxvkAllocationModes mode = 0u;
VkDeviceSize size = 0u;
};
dxvk::mutex m_mutex;
std::unordered_map<Rc<DxvkPagedResource>,
DxvkAllocationModes, RcHash> m_entries;
Entry, RcHash> m_entries;
};
@ -1243,11 +1252,12 @@ namespace dxvk {
/**
* \brief Polls relocation list
*
* \param [in] count Desired entry count
* \param [in] count Maximum resource count
* \param [in] size Maximum total size
* \returns Relocation entries
*/
auto pollRelocationList(uint32_t count) {
return m_relocations.poll(count);
auto pollRelocationList(uint32_t count, VkDeviceSize size) {
return m_relocations.poll(count, size);
}
private: