1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-13 19:29:14 +01:00

[dxvk] Do not defragment chunks with immovable resources

This commit is contained in:
Philip Rebohle 2024-10-23 19:43:04 +02:00 committed by Philip Rebohle
parent 62f266098e
commit 9977313c32
3 changed files with 48 additions and 5 deletions

View File

@ -1419,7 +1419,11 @@ namespace dxvk {
void DxvkContext::ensureBufferAddress(
const Rc<DxvkBuffer>& buffer) {
// Really nothing else to do here but set the flag
buffer->enableStableAddress();
if (buffer->canRelocate()) {
buffer->enableStableAddress();
m_common->memoryManager().lockResourceGpuAddress(buffer->storage());
}
}
@ -1440,6 +1444,9 @@ namespace dxvk {
Rc<DxvkResourceAllocation> prevAllocation = image->assignStorageWithUsage(std::move(slice), usageInfo);
m_cmd->track(std::move(prevAllocation));
if (usageInfo.stableGpuAddress)
m_common->memoryManager().lockResourceGpuAddress(image->storage());
VkImageUsageFlags usage = image->info().usage;
if (usage & (VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT))
@ -1478,8 +1485,10 @@ namespace dxvk {
// If everything matches already, no need to do anything. Only ensure
// that the stable adress bit is respected if set for the first time.
if (isUsageAndFormatCompatible && isAccessAndLayoutCompatible) {
if (usageInfo.stableGpuAddress && image->canRelocate())
if (usageInfo.stableGpuAddress && image->canRelocate()) {
image->assignStorageWithUsage(image->storage(), usageInfo);
m_common->memoryManager().lockResourceGpuAddress(image->storage());
}
return true;
}
@ -1498,6 +1507,9 @@ namespace dxvk {
image->assignStorageWithUsage(image->storage(), usageInfo);
if (usageInfo.stableGpuAddress)
m_common->memoryManager().lockResourceGpuAddress(image->storage());
accessImage(DxvkCmdBuffer::ExecBuffer, *image, image->getAvailableSubresources(),
oldLayout, image->info().stages, image->info().access,
newLayout, image->info().stages, image->info().access);

View File

@ -1225,6 +1225,7 @@ namespace dxvk {
pool.chunks[chunkIndex].memory = chunk;
pool.chunks[chunkIndex].unusedTime = high_resolution_clock::time_point();
pool.chunks[chunkIndex].chunkCookie = ++pool.nextChunkCookie;
pool.chunks[chunkIndex].canMove = true;
return true;
}
@ -1351,6 +1352,9 @@ namespace dxvk {
}
if (unlikely(pool.free(allocation->m_address, allocation->m_size))) {
uint32_t chunkIndex = allocation->m_address >> DxvkPageAllocator::ChunkAddressBits;
pool.chunks[chunkIndex].canMove = true;
if (freeEmptyChunksInPool(*allocation->m_type, pool, 0, high_resolution_clock::now()))
updateMemoryHeapStats(allocation->m_type->properties.heapIndex);
}
@ -1969,6 +1973,20 @@ namespace dxvk {
}
void DxvkMemoryAllocator::lockResourceGpuAddress(
const Rc<DxvkResourceAllocation>& allocation) {
if (allocation->m_flags.test(DxvkAllocationFlag::CanMove)) {
std::lock_guard lock(m_resourceMutex);
allocation->m_flags.clr(DxvkAllocationFlag::CanMove);
if (!allocation->m_flags.test(DxvkAllocationFlag::OwnsMemory) && !allocation->m_mapPtr) {
uint32_t chunkIndex = allocation->m_address >> DxvkPageAllocator::ChunkAddressBits;
allocation->m_type->devicePool.chunks[chunkIndex].canMove = false;
}
}
}
VkDeviceAddress DxvkMemoryAllocator::getBufferDeviceAddress(VkBuffer buffer) const {
auto vk = m_device->vkd();
@ -2107,9 +2125,6 @@ namespace dxvk {
std::unique_lock lock(m_resourceMutex);
for (auto a = pool.chunks[chunkIndex].allocationList; a; a = a->m_nextInChunk) {
if (!a->m_flags.test(DxvkAllocationFlag::CanMove))
continue;
// If we can't find the resource by its cookie, it has probably
// already been destroyed. This is fine since the allocation will
// likely get freed soon anyway.
@ -2175,6 +2190,10 @@ namespace dxvk {
continue;
}
// Move on if the chunk cannot be relocated anyway
if (!pool.chunks[i].canMove)
continue;
// If there's a non-empty chunk already marked as dead and we haven't
// finished moving resources around yet, killing another chunk would
// do more harm than good so wait for that to finish first.

View File

@ -84,6 +84,9 @@ namespace dxvk {
DxvkResourceAllocation* allocationList = nullptr;
/// Chunk cookie
uint32_t chunkCookie = 0u;
/// Whether defragmentation can be performed on this chunk.
/// Only relevant for chunks in non-mappable device memory.
VkBool32 canMove = true;
void addAllocation(DxvkResourceAllocation* allocation);
void removeAllocation(DxvkResourceAllocation* allocation);
@ -1240,6 +1243,15 @@ namespace dxvk {
void unregisterResource(
DxvkPagedResource* resource);
/**
* \brief Locks an allocation in place
*
* Ensures that the resource is marked as immovable so
* that defragmentation won't attempt to relocate it.
*/
void lockResourceGpuAddress(
const Rc<DxvkResourceAllocation>& allocation);
/**
* \brief Performs clean-up tasks
*