Merge pull request #6465 from FernandoS27/sex-on-the-beach

GPU: Implement a garbage collector for GPU Caches (project Reaper+)
This commit is contained in:
Mai M 2021-06-23 08:03:01 -04:00 committed by GitHub
commit 17fff10e06
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 493 additions and 63 deletions

View file

@ -408,6 +408,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
}
logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld);
CollectPhysicalMemoryInfo();
CollectTelemetryParameters();
CollectToolingInfo();
@ -818,6 +819,17 @@ void Device::CollectTelemetryParameters() {
}
}
void Device::CollectPhysicalMemoryInfo() {
const auto mem_properties = physical.GetMemoryProperties();
const std::size_t num_properties = mem_properties.memoryHeapCount;
device_access_memory = 0;
for (std::size_t element = 0; element < num_properties; element++) {
if ((mem_properties.memoryHeaps[element].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) {
device_access_memory += mem_properties.memoryHeaps[element].size;
}
}
}
void Device::CollectToolingInfo() {
if (!ext_tooling_info) {
return;

View file

@ -225,6 +225,10 @@ public:
return use_asynchronous_shaders;
}
u64 GetDeviceLocalMemory() const {
return device_access_memory;
}
private:
/// Checks if the physical device is suitable.
void CheckSuitability(bool requires_swapchain) const;
@ -244,6 +248,9 @@ private:
/// Collects information about attached tools.
void CollectToolingInfo();
/// Collects information about the device's local memory.
void CollectPhysicalMemoryInfo();
/// Returns a list of queue initialization descriptors.
std::vector<VkDeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const;
@ -302,6 +309,8 @@ private:
/// Nsight Aftermath GPU crash tracker
std::unique_ptr<NsightAftermathTracker> nsight_aftermath_tracker;
u64 device_access_memory;
};
} // namespace Vulkan

View file

@ -69,10 +69,10 @@ constexpr VkExportMemoryAllocateInfo EXPORT_ALLOCATE_INFO{
class MemoryAllocation {
public:
explicit MemoryAllocation(vk::DeviceMemory memory_, VkMemoryPropertyFlags properties,
u64 allocation_size_, u32 type)
: memory{std::move(memory_)}, allocation_size{allocation_size_}, property_flags{properties},
shifted_memory_type{1U << type} {}
explicit MemoryAllocation(MemoryAllocator* const allocator_, vk::DeviceMemory memory_,
VkMemoryPropertyFlags properties, u64 allocation_size_, u32 type)
: allocator{allocator_}, memory{std::move(memory_)}, allocation_size{allocation_size_},
property_flags{properties}, shifted_memory_type{1U << type} {}
#if defined(_WIN32) || defined(__unix__)
~MemoryAllocation() {
@ -106,6 +106,10 @@ public:
const auto it = std::ranges::find(commits, begin, &Range::begin);
ASSERT_MSG(it != commits.end(), "Invalid commit");
commits.erase(it);
if (commits.empty()) {
// Do not call any code involving 'this' after this call, the object will be destroyed
allocator->ReleaseMemory(this);
}
}
[[nodiscard]] std::span<u8> Map() {
@ -171,6 +175,7 @@ private:
return candidate;
}
MemoryAllocator* const allocator; ///< Parent memory allocation.
const vk::DeviceMemory memory; ///< Vulkan memory allocation handler.
const u64 allocation_size; ///< Size of this allocation.
const VkMemoryPropertyFlags property_flags; ///< Vulkan memory property flags.
@ -275,10 +280,17 @@ bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask,
return false;
}
}
allocations.push_back(std::make_unique<MemoryAllocation>(std::move(memory), flags, size, type));
allocations.push_back(
std::make_unique<MemoryAllocation>(this, std::move(memory), flags, size, type));
return true;
}
void MemoryAllocator::ReleaseMemory(MemoryAllocation* alloc) {
const auto it = std::ranges::find(allocations, alloc, &std::unique_ptr<MemoryAllocation>::get);
ASSERT(it != allocations.end());
allocations.erase(it);
}
std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements,
VkMemoryPropertyFlags flags) {
for (auto& allocation : allocations) {

View file

@ -69,6 +69,8 @@ private:
/// Memory allocator container.
/// Allocates and releases memory allocations on demand.
class MemoryAllocator {
friend MemoryAllocation;
public:
/**
* Construct memory allocator
@ -104,6 +106,9 @@ private:
/// Tries to allocate a chunk of memory.
bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size);
/// Releases a chunk of memory.
void ReleaseMemory(MemoryAllocation* alloc);
/// Tries to allocate a memory commit.
std::optional<MemoryCommit> TryCommit(const VkMemoryRequirements& requirements,
VkMemoryPropertyFlags flags);