diff options
| author | 2021-06-23 08:03:01 -0400 | |
|---|---|---|
| committer | 2021-06-23 08:03:01 -0400 | |
| commit | 17fff10e06e7935522a5a69705b9a750761aab79 (patch) | |
| tree | 7e7b3ae9fedbc0fed85f6c5c58e92e8d047efd87 /src/video_core/vulkan_common | |
| parent | Merge pull request #6508 from ReinUsesLisp/bootmanager-stop-token (diff) | |
| parent | Reaper: Set minimum cleaning limit on OGL. (diff) | |
| download | yuzu-17fff10e06e7935522a5a69705b9a750761aab79.tar.gz yuzu-17fff10e06e7935522a5a69705b9a750761aab79.tar.xz yuzu-17fff10e06e7935522a5a69705b9a750761aab79.zip | |
Merge pull request #6465 from FernandoS27/sex-on-the-beach
GPU: Implement a garbage collector for GPU Caches (project Reaper+)
Diffstat (limited to 'src/video_core/vulkan_common')
4 files changed, 43 insertions, 5 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 64206b3d2..707a8b8fb 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -408,6 +408,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 408 | } | 408 | } |
| 409 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); | 409 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); |
| 410 | 410 | ||
| 411 | CollectPhysicalMemoryInfo(); | ||
| 411 | CollectTelemetryParameters(); | 412 | CollectTelemetryParameters(); |
| 412 | CollectToolingInfo(); | 413 | CollectToolingInfo(); |
| 413 | 414 | ||
| @@ -818,6 +819,17 @@ void Device::CollectTelemetryParameters() { | |||
| 818 | } | 819 | } |
| 819 | } | 820 | } |
| 820 | 821 | ||
| 822 | void Device::CollectPhysicalMemoryInfo() { | ||
| 823 | const auto mem_properties = physical.GetMemoryProperties(); | ||
| 824 | const std::size_t num_properties = mem_properties.memoryHeapCount; | ||
| 825 | device_access_memory = 0; | ||
| 826 | for (std::size_t element = 0; element < num_properties; element++) { | ||
| 827 | if ((mem_properties.memoryHeaps[element].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) { | ||
| 828 | device_access_memory += mem_properties.memoryHeaps[element].size; | ||
| 829 | } | ||
| 830 | } | ||
| 831 | } | ||
| 832 | |||
| 821 | void Device::CollectToolingInfo() { | 833 | void Device::CollectToolingInfo() { |
| 822 | if (!ext_tooling_info) { | 834 | if (!ext_tooling_info) { |
| 823 | return; | 835 | return; |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 67d70cd22..a1aba973b 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -225,6 +225,10 @@ public: | |||
| 225 | return use_asynchronous_shaders; | 225 | return use_asynchronous_shaders; |
| 226 | } | 226 | } |
| 227 | 227 | ||
| 228 | u64 GetDeviceLocalMemory() const { | ||
| 229 | return device_access_memory; | ||
| 230 | } | ||
| 231 | |||
| 228 | private: | 232 | private: |
| 229 | /// Checks if the physical device is suitable. | 233 | /// Checks if the physical device is suitable. |
| 230 | void CheckSuitability(bool requires_swapchain) const; | 234 | void CheckSuitability(bool requires_swapchain) const; |
| @@ -244,6 +248,9 @@ private: | |||
| 244 | /// Collects information about attached tools. | 248 | /// Collects information about attached tools. |
| 245 | void CollectToolingInfo(); | 249 | void CollectToolingInfo(); |
| 246 | 250 | ||
| 251 | /// Collects information about the device's local memory. | ||
| 252 | void CollectPhysicalMemoryInfo(); | ||
| 253 | |||
| 247 | /// Returns a list of queue initialization descriptors. | 254 | /// Returns a list of queue initialization descriptors. |
| 248 | std::vector<VkDeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const; | 255 | std::vector<VkDeviceQueueCreateInfo> GetDeviceQueueCreateInfos() const; |
| 249 | 256 | ||
| @@ -302,6 +309,8 @@ private: | |||
| 302 | 309 | ||
| 303 | /// Nsight Aftermath GPU crash tracker | 310 | /// Nsight Aftermath GPU crash tracker |
| 304 | std::unique_ptr<NsightAftermathTracker> nsight_aftermath_tracker; | 311 | std::unique_ptr<NsightAftermathTracker> nsight_aftermath_tracker; |
| 312 | |||
| 313 | u64 device_access_memory; | ||
| 305 | }; | 314 | }; |
| 306 | 315 | ||
| 307 | } // namespace Vulkan | 316 | } // namespace Vulkan |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 5edd06ebc..aa173d19e 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -69,10 +69,10 @@ constexpr VkExportMemoryAllocateInfo EXPORT_ALLOCATE_INFO{ | |||
| 69 | 69 | ||
| 70 | class MemoryAllocation { | 70 | class MemoryAllocation { |
| 71 | public: | 71 | public: |
| 72 | explicit MemoryAllocation(vk::DeviceMemory memory_, VkMemoryPropertyFlags properties, | 72 | explicit MemoryAllocation(MemoryAllocator* const allocator_, vk::DeviceMemory memory_, |
| 73 | u64 allocation_size_, u32 type) | 73 | VkMemoryPropertyFlags properties, u64 allocation_size_, u32 type) |
| 74 | : memory{std::move(memory_)}, allocation_size{allocation_size_}, property_flags{properties}, | 74 | : allocator{allocator_}, memory{std::move(memory_)}, allocation_size{allocation_size_}, |
| 75 | shifted_memory_type{1U << type} {} | 75 | property_flags{properties}, shifted_memory_type{1U << type} {} |
| 76 | 76 | ||
| 77 | #if defined(_WIN32) || defined(__unix__) | 77 | #if defined(_WIN32) || defined(__unix__) |
| 78 | ~MemoryAllocation() { | 78 | ~MemoryAllocation() { |
| @@ -106,6 +106,10 @@ public: | |||
| 106 | const auto it = std::ranges::find(commits, begin, &Range::begin); | 106 | const auto it = std::ranges::find(commits, begin, &Range::begin); |
| 107 | ASSERT_MSG(it != commits.end(), "Invalid commit"); | 107 | ASSERT_MSG(it != commits.end(), "Invalid commit"); |
| 108 | commits.erase(it); | 108 | commits.erase(it); |
| 109 | if (commits.empty()) { | ||
| 110 | // Do not call any code involving 'this' after this call, the object will be destroyed | ||
| 111 | allocator->ReleaseMemory(this); | ||
| 112 | } | ||
| 109 | } | 113 | } |
| 110 | 114 | ||
| 111 | [[nodiscard]] std::span<u8> Map() { | 115 | [[nodiscard]] std::span<u8> Map() { |
| @@ -171,6 +175,7 @@ private: | |||
| 171 | return candidate; | 175 | return candidate; |
| 172 | } | 176 | } |
| 173 | 177 | ||
| 178 | MemoryAllocator* const allocator; ///< Parent memory allocation. | ||
| 174 | const vk::DeviceMemory memory; ///< Vulkan memory allocation handler. | 179 | const vk::DeviceMemory memory; ///< Vulkan memory allocation handler. |
| 175 | const u64 allocation_size; ///< Size of this allocation. | 180 | const u64 allocation_size; ///< Size of this allocation. |
| 176 | const VkMemoryPropertyFlags property_flags; ///< Vulkan memory property flags. | 181 | const VkMemoryPropertyFlags property_flags; ///< Vulkan memory property flags. |
| @@ -275,10 +280,17 @@ bool MemoryAllocator::TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, | |||
| 275 | return false; | 280 | return false; |
| 276 | } | 281 | } |
| 277 | } | 282 | } |
| 278 | allocations.push_back(std::make_unique<MemoryAllocation>(std::move(memory), flags, size, type)); | 283 | allocations.push_back( |
| 284 | std::make_unique<MemoryAllocation>(this, std::move(memory), flags, size, type)); | ||
| 279 | return true; | 285 | return true; |
| 280 | } | 286 | } |
| 281 | 287 | ||
| 288 | void MemoryAllocator::ReleaseMemory(MemoryAllocation* alloc) { | ||
| 289 | const auto it = std::ranges::find(allocations, alloc, &std::unique_ptr<MemoryAllocation>::get); | ||
| 290 | ASSERT(it != allocations.end()); | ||
| 291 | allocations.erase(it); | ||
| 292 | } | ||
| 293 | |||
| 282 | std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements, | 294 | std::optional<MemoryCommit> MemoryAllocator::TryCommit(const VkMemoryRequirements& requirements, |
| 283 | VkMemoryPropertyFlags flags) { | 295 | VkMemoryPropertyFlags flags) { |
| 284 | for (auto& allocation : allocations) { | 296 | for (auto& allocation : allocations) { |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.h b/src/video_core/vulkan_common/vulkan_memory_allocator.h index db12d02f4..b61e931e0 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.h +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.h | |||
| @@ -69,6 +69,8 @@ private: | |||
| 69 | /// Memory allocator container. | 69 | /// Memory allocator container. |
| 70 | /// Allocates and releases memory allocations on demand. | 70 | /// Allocates and releases memory allocations on demand. |
| 71 | class MemoryAllocator { | 71 | class MemoryAllocator { |
| 72 | friend MemoryAllocation; | ||
| 73 | |||
| 72 | public: | 74 | public: |
| 73 | /** | 75 | /** |
| 74 | * Construct memory allocator | 76 | * Construct memory allocator |
| @@ -104,6 +106,9 @@ private: | |||
| 104 | /// Tries to allocate a chunk of memory. | 106 | /// Tries to allocate a chunk of memory. |
| 105 | bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); | 107 | bool TryAllocMemory(VkMemoryPropertyFlags flags, u32 type_mask, u64 size); |
| 106 | 108 | ||
| 109 | /// Releases a chunk of memory. | ||
| 110 | void ReleaseMemory(MemoryAllocation* alloc); | ||
| 111 | |||
| 107 | /// Tries to allocate a memory commit. | 112 | /// Tries to allocate a memory commit. |
| 108 | std::optional<MemoryCommit> TryCommit(const VkMemoryRequirements& requirements, | 113 | std::optional<MemoryCommit> TryCommit(const VkMemoryRequirements& requirements, |
| 109 | VkMemoryPropertyFlags flags); | 114 | VkMemoryPropertyFlags flags); |