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:
parent
62f266098e
commit
9977313c32
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*
|
||||
|
Loading…
x
Reference in New Issue
Block a user