diff options
| author | 2022-01-16 04:43:06 +0100 | |
|---|---|---|
| committer | 2022-03-25 01:51:51 +0100 | |
| commit | ecb3342145780d811017a3a3c8f14f3e0725db75 (patch) | |
| tree | 2badf5f2b54a90cc3803d63f9f013c6abe1a6a2d /src/video_core/vulkan_common | |
| parent | Merge pull request #8074 from liamwhite/cached-words (diff) | |
| download | yuzu-ecb3342145780d811017a3a3c8f14f3e0725db75.tar.gz yuzu-ecb3342145780d811017a3a3c8f14f3e0725db75.tar.xz yuzu-ecb3342145780d811017a3a3c8f14f3e0725db75.zip | |
Garbage Collection: Redesign the algorithm to do a better use of memory.
Diffstat (limited to 'src/video_core/vulkan_common')
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 52 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 11 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_memory_allocator.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.cpp | 13 | ||||
| -rw-r--r-- | src/video_core/vulkan_common/vulkan_wrapper.h | 4 |
5 files changed, 71 insertions, 11 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 32c10d675..dab5b4fe4 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp | |||
| @@ -12,12 +12,14 @@ | |||
| 12 | #include <vector> | 12 | #include <vector> |
| 13 | 13 | ||
| 14 | #include "common/assert.h" | 14 | #include "common/assert.h" |
| 15 | #include "common/literals.h" | ||
| 15 | #include "common/settings.h" | 16 | #include "common/settings.h" |
| 16 | #include "video_core/vulkan_common/nsight_aftermath_tracker.h" | 17 | #include "video_core/vulkan_common/nsight_aftermath_tracker.h" |
| 17 | #include "video_core/vulkan_common/vulkan_device.h" | 18 | #include "video_core/vulkan_common/vulkan_device.h" |
| 18 | #include "video_core/vulkan_common/vulkan_wrapper.h" | 19 | #include "video_core/vulkan_common/vulkan_wrapper.h" |
| 19 | 20 | ||
| 20 | namespace Vulkan { | 21 | namespace Vulkan { |
| 22 | using namespace Common::Literals; | ||
| 21 | namespace { | 23 | namespace { |
| 22 | namespace Alternatives { | 24 | namespace Alternatives { |
| 23 | constexpr std::array STENCIL8_UINT{ | 25 | constexpr std::array STENCIL8_UINT{ |
| @@ -596,6 +598,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 596 | } | 598 | } |
| 597 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); | 599 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); |
| 598 | 600 | ||
| 601 | is_integrated = (properties.deviceType & VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) != 0; | ||
| 602 | is_virtual = (properties.deviceType & VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU) != 0; | ||
| 603 | is_non_gpu = (properties.deviceType & VK_PHYSICAL_DEVICE_TYPE_OTHER) != 0 || | ||
| 604 | (properties.deviceType & VK_PHYSICAL_DEVICE_TYPE_CPU) != 0; | ||
| 605 | |||
| 599 | CollectPhysicalMemoryInfo(); | 606 | CollectPhysicalMemoryInfo(); |
| 600 | CollectTelemetryParameters(); | 607 | CollectTelemetryParameters(); |
| 601 | CollectToolingInfo(); | 608 | CollectToolingInfo(); |
| @@ -985,6 +992,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 985 | test(has_khr_swapchain_mutable_format, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, | 992 | test(has_khr_swapchain_mutable_format, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, |
| 986 | false); | 993 | false); |
| 987 | test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false); | 994 | test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false); |
| 995 | test(ext_memory_budget, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, true); | ||
| 988 | if (Settings::values.enable_nsight_aftermath) { | 996 | if (Settings::values.enable_nsight_aftermath) { |
| 989 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, | 997 | test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, |
| 990 | true); | 998 | true); |
| @@ -997,7 +1005,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { | |||
| 997 | VkPhysicalDeviceFeatures2KHR features{}; | 1005 | VkPhysicalDeviceFeatures2KHR features{}; |
| 998 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; | 1006 | features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; |
| 999 | 1007 | ||
| 1000 | VkPhysicalDeviceProperties2KHR physical_properties; | 1008 | VkPhysicalDeviceProperties2KHR physical_properties{}; |
| 1001 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; | 1009 | physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; |
| 1002 | 1010 | ||
| 1003 | if (has_khr_shader_float16_int8) { | 1011 | if (has_khr_shader_float16_int8) { |
| @@ -1267,15 +1275,51 @@ void Device::CollectTelemetryParameters() { | |||
| 1267 | vendor_name = driver.driverName; | 1275 | vendor_name = driver.driverName; |
| 1268 | } | 1276 | } |
| 1269 | 1277 | ||
| 1278 | u64 Device::GetDeviceMemoryUsage() const { | ||
| 1279 | VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; | ||
| 1280 | budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; | ||
| 1281 | budget.pNext = nullptr; | ||
| 1282 | physical.GetMemoryProperties(&budget); | ||
| 1283 | u64 result{}; | ||
| 1284 | for (const size_t heap : valid_heap_memory) { | ||
| 1285 | result += budget.heapUsage[heap]; | ||
| 1286 | } | ||
| 1287 | return result; | ||
| 1288 | } | ||
| 1289 | |||
| 1270 | void Device::CollectPhysicalMemoryInfo() { | 1290 | void Device::CollectPhysicalMemoryInfo() { |
| 1271 | const auto mem_properties = physical.GetMemoryProperties(); | 1291 | VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; |
| 1292 | budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; | ||
| 1293 | const auto mem_info = physical.GetMemoryProperties(ext_memory_budget ? &budget : nullptr); | ||
| 1294 | const auto& mem_properties = mem_info.memoryProperties; | ||
| 1272 | const size_t num_properties = mem_properties.memoryHeapCount; | 1295 | const size_t num_properties = mem_properties.memoryHeapCount; |
| 1273 | device_access_memory = 0; | 1296 | device_access_memory = 0; |
| 1297 | u64 device_initial_usage = 0; | ||
| 1298 | u64 local_memory = 0; | ||
| 1274 | for (size_t element = 0; element < num_properties; ++element) { | 1299 | for (size_t element = 0; element < num_properties; ++element) { |
| 1275 | if ((mem_properties.memoryHeaps[element].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0) { | 1300 | const bool is_heap_local = |
| 1276 | device_access_memory += mem_properties.memoryHeaps[element].size; | 1301 | mem_properties.memoryHeaps[element].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT != 0; |
| 1302 | if (!is_integrated && !is_heap_local) { | ||
| 1303 | continue; | ||
| 1277 | } | 1304 | } |
| 1305 | valid_heap_memory.push_back(element); | ||
| 1306 | if (is_heap_local) { | ||
| 1307 | local_memory += mem_properties.memoryHeaps[element].size; | ||
| 1308 | } | ||
| 1309 | if (ext_memory_budget) { | ||
| 1310 | device_initial_usage += budget.heapUsage[element]; | ||
| 1311 | device_access_memory += budget.heapBudget[element]; | ||
| 1312 | continue; | ||
| 1313 | } | ||
| 1314 | device_access_memory += mem_properties.memoryHeaps[element].size; | ||
| 1315 | } | ||
| 1316 | if (!is_integrated) { | ||
| 1317 | return; | ||
| 1278 | } | 1318 | } |
| 1319 | const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); | ||
| 1320 | device_access_memory = static_cast<u64>(std::max<s64>( | ||
| 1321 | std::min<s64>(available_memory - 8_GiB, 4_GiB), static_cast<s64>(local_memory))); | ||
| 1322 | device_initial_usage = 0; | ||
| 1279 | } | 1323 | } |
| 1280 | 1324 | ||
| 1281 | void Device::CollectToolingInfo() { | 1325 | void Device::CollectToolingInfo() { |
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 1c7c18bcf..2d709d069 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h | |||
| @@ -341,6 +341,12 @@ public: | |||
| 341 | return device_access_memory; | 341 | return device_access_memory; |
| 342 | } | 342 | } |
| 343 | 343 | ||
| 344 | bool CanReportMemoryUsage() const { | ||
| 345 | return ext_memory_budget; | ||
| 346 | } | ||
| 347 | |||
| 348 | u64 GetDeviceMemoryUsage() const; | ||
| 349 | |||
| 344 | u32 GetSetsPerPool() const { | 350 | u32 GetSetsPerPool() const { |
| 345 | return sets_per_pool; | 351 | return sets_per_pool; |
| 346 | } | 352 | } |
| @@ -421,6 +427,9 @@ private: | |||
| 421 | bool is_topology_list_restart_supported{}; ///< Support for primitive restart with list | 427 | bool is_topology_list_restart_supported{}; ///< Support for primitive restart with list |
| 422 | ///< topologies. | 428 | ///< topologies. |
| 423 | bool is_patch_list_restart_supported{}; ///< Support for primitive restart with list patch. | 429 | bool is_patch_list_restart_supported{}; ///< Support for primitive restart with list patch. |
| 430 | bool is_integrated{}; ///< Is GPU an iGPU. | ||
| 431 | bool is_virtual{}; ///< Is GPU a virtual GPU. | ||
| 432 | bool is_non_gpu{}; ///< Is SoftwareRasterizer, FPGA, non-GPU device. | ||
| 424 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. | 433 | bool nv_viewport_swizzle{}; ///< Support for VK_NV_viewport_swizzle. |
| 425 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. | 434 | bool nv_viewport_array2{}; ///< Support for VK_NV_viewport_array2. |
| 426 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. | 435 | bool nv_geometry_shader_passthrough{}; ///< Support for VK_NV_geometry_shader_passthrough. |
| @@ -445,6 +454,7 @@ private: | |||
| 445 | bool ext_shader_atomic_int64{}; ///< Support for VK_KHR_shader_atomic_int64. | 454 | bool ext_shader_atomic_int64{}; ///< Support for VK_KHR_shader_atomic_int64. |
| 446 | bool ext_conservative_rasterization{}; ///< Support for VK_EXT_conservative_rasterization. | 455 | bool ext_conservative_rasterization{}; ///< Support for VK_EXT_conservative_rasterization. |
| 447 | bool ext_provoking_vertex{}; ///< Support for VK_EXT_provoking_vertex. | 456 | bool ext_provoking_vertex{}; ///< Support for VK_EXT_provoking_vertex. |
| 457 | bool ext_memory_budget{}; ///< Support for VK_EXT_memory_budget. | ||
| 448 | bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. | 458 | bool nv_device_diagnostics_config{}; ///< Support for VK_NV_device_diagnostics_config. |
| 449 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit | 459 | bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit |
| 450 | bool has_renderdoc{}; ///< Has RenderDoc attached | 460 | bool has_renderdoc{}; ///< Has RenderDoc attached |
| @@ -456,6 +466,7 @@ private: | |||
| 456 | // Telemetry parameters | 466 | // Telemetry parameters |
| 457 | std::string vendor_name; ///< Device's driver name. | 467 | std::string vendor_name; ///< Device's driver name. |
| 458 | std::vector<std::string> supported_extensions; ///< Reported Vulkan extensions. | 468 | std::vector<std::string> supported_extensions; ///< Reported Vulkan extensions. |
| 469 | std::vector<size_t> valid_heap_memory; ///< Heaps used. | ||
| 459 | 470 | ||
| 460 | /// Format properties dictionary. | 471 | /// Format properties dictionary. |
| 461 | std::unordered_map<VkFormat, VkFormatProperties> format_properties; | 472 | std::unordered_map<VkFormat, VkFormatProperties> format_properties; |
diff --git a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp index 300a61205..e6e97b332 100644 --- a/src/video_core/vulkan_common/vulkan_memory_allocator.cpp +++ b/src/video_core/vulkan_common/vulkan_memory_allocator.cpp | |||
| @@ -227,7 +227,7 @@ void MemoryCommit::Release() { | |||
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | MemoryAllocator::MemoryAllocator(const Device& device_, bool export_allocations_) | 229 | MemoryAllocator::MemoryAllocator(const Device& device_, bool export_allocations_) |
| 230 | : device{device_}, properties{device_.GetPhysical().GetMemoryProperties()}, | 230 | : device{device_}, properties{device_.GetPhysical().GetMemoryProperties().memoryProperties}, |
| 231 | export_allocations{export_allocations_}, | 231 | export_allocations{export_allocations_}, |
| 232 | buffer_image_granularity{ | 232 | buffer_image_granularity{ |
| 233 | device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {} | 233 | device_.GetPhysical().GetProperties().limits.bufferImageGranularity} {} |
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.cpp b/src/video_core/vulkan_common/vulkan_wrapper.cpp index a794f16dd..742cc39da 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.cpp +++ b/src/video_core/vulkan_common/vulkan_wrapper.cpp | |||
| @@ -237,8 +237,8 @@ bool Load(VkInstance instance, InstanceDispatch& dld) noexcept { | |||
| 237 | return X(vkCreateDevice) && X(vkDestroyDevice) && X(vkDestroyDevice) && | 237 | return X(vkCreateDevice) && X(vkDestroyDevice) && X(vkDestroyDevice) && |
| 238 | X(vkEnumerateDeviceExtensionProperties) && X(vkEnumeratePhysicalDevices) && | 238 | X(vkEnumerateDeviceExtensionProperties) && X(vkEnumeratePhysicalDevices) && |
| 239 | X(vkGetDeviceProcAddr) && X(vkGetPhysicalDeviceFormatProperties) && | 239 | X(vkGetDeviceProcAddr) && X(vkGetPhysicalDeviceFormatProperties) && |
| 240 | X(vkGetPhysicalDeviceMemoryProperties) && X(vkGetPhysicalDeviceProperties) && | 240 | X(vkGetPhysicalDeviceMemoryProperties) && X(vkGetPhysicalDeviceMemoryProperties2) && |
| 241 | X(vkGetPhysicalDeviceQueueFamilyProperties); | 241 | X(vkGetPhysicalDeviceProperties) && X(vkGetPhysicalDeviceQueueFamilyProperties); |
| 242 | #undef X | 242 | #undef X |
| 243 | } | 243 | } |
| 244 | 244 | ||
| @@ -926,9 +926,12 @@ std::vector<VkPresentModeKHR> PhysicalDevice::GetSurfacePresentModesKHR( | |||
| 926 | return modes; | 926 | return modes; |
| 927 | } | 927 | } |
| 928 | 928 | ||
| 929 | VkPhysicalDeviceMemoryProperties PhysicalDevice::GetMemoryProperties() const noexcept { | 929 | VkPhysicalDeviceMemoryProperties2 PhysicalDevice::GetMemoryProperties( |
| 930 | VkPhysicalDeviceMemoryProperties properties; | 930 | void* next_structures) const noexcept { |
| 931 | dld->vkGetPhysicalDeviceMemoryProperties(physical_device, &properties); | 931 | VkPhysicalDeviceMemoryProperties2 properties{}; |
| 932 | properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_PROPERTIES_2; | ||
| 933 | properties.pNext = next_structures; | ||
| 934 | dld->vkGetPhysicalDeviceMemoryProperties2(physical_device, &properties); | ||
| 932 | return properties; | 935 | return properties; |
| 933 | } | 936 | } |
| 934 | 937 | ||
diff --git a/src/video_core/vulkan_common/vulkan_wrapper.h b/src/video_core/vulkan_common/vulkan_wrapper.h index 53bac627f..0a5f9931c 100644 --- a/src/video_core/vulkan_common/vulkan_wrapper.h +++ b/src/video_core/vulkan_common/vulkan_wrapper.h | |||
| @@ -172,6 +172,7 @@ struct InstanceDispatch { | |||
| 172 | PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR{}; | 172 | PFN_vkGetPhysicalDeviceFeatures2KHR vkGetPhysicalDeviceFeatures2KHR{}; |
| 173 | PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties{}; | 173 | PFN_vkGetPhysicalDeviceFormatProperties vkGetPhysicalDeviceFormatProperties{}; |
| 174 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties{}; | 174 | PFN_vkGetPhysicalDeviceMemoryProperties vkGetPhysicalDeviceMemoryProperties{}; |
| 175 | PFN_vkGetPhysicalDeviceMemoryProperties2 vkGetPhysicalDeviceMemoryProperties2{}; | ||
| 175 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties{}; | 176 | PFN_vkGetPhysicalDeviceProperties vkGetPhysicalDeviceProperties{}; |
| 176 | PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR{}; | 177 | PFN_vkGetPhysicalDeviceProperties2KHR vkGetPhysicalDeviceProperties2KHR{}; |
| 177 | PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties{}; | 178 | PFN_vkGetPhysicalDeviceQueueFamilyProperties vkGetPhysicalDeviceQueueFamilyProperties{}; |
| @@ -950,7 +951,8 @@ public: | |||
| 950 | 951 | ||
| 951 | std::vector<VkPresentModeKHR> GetSurfacePresentModesKHR(VkSurfaceKHR) const; | 952 | std::vector<VkPresentModeKHR> GetSurfacePresentModesKHR(VkSurfaceKHR) const; |
| 952 | 953 | ||
| 953 | VkPhysicalDeviceMemoryProperties GetMemoryProperties() const noexcept; | 954 | VkPhysicalDeviceMemoryProperties2 GetMemoryProperties( |
| 955 | void* next_structures = nullptr) const noexcept; | ||
| 954 | 956 | ||
| 955 | private: | 957 | private: |
| 956 | VkPhysicalDevice physical_device = nullptr; | 958 | VkPhysicalDevice physical_device = nullptr; |