diff options
Diffstat (limited to '')
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 75 |
1 files changed, 67 insertions, 8 deletions
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 32c10d675..7b2ca8046 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -1,6 +1,5 @@ -// Copyright 2018 yuzu Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later #include <algorithm> #include <bitset> @@ -12,12 +11,14 @@ #include <vector> #include "common/assert.h" +#include "common/literals.h" #include "common/settings.h" #include "video_core/vulkan_common/nsight_aftermath_tracker.h" #include "video_core/vulkan_common/vulkan_device.h" #include "video_core/vulkan_common/vulkan_wrapper.h" namespace Vulkan { +using namespace Common::Literals; namespace { namespace Alternatives { constexpr std::array STENCIL8_UINT{ @@ -43,6 +44,12 @@ constexpr std::array B5G6R5_UNORM_PACK16{ VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_UNDEFINED, }; + +constexpr std::array R4G4_UNORM_PACK8{ + VK_FORMAT_R8_UNORM, + VK_FORMAT_UNDEFINED, +}; + } // namespace Alternatives enum class NvidiaArchitecture { @@ -93,6 +100,8 @@ constexpr const VkFormat* GetFormatAlternatives(VkFormat format) { return Alternatives::DEPTH16_UNORM_STENCIL8_UINT.data(); case VK_FORMAT_B5G6R5_UNORM_PACK16: return Alternatives::B5G6R5_UNORM_PACK16.data(); + case VK_FORMAT_R4G4_UNORM_PACK8: + return Alternatives::R4G4_UNORM_PACK8.data(); default: return nullptr; } @@ -120,6 +129,8 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica VK_FORMAT_A8B8G8R8_SRGB_PACK32, VK_FORMAT_R5G6B5_UNORM_PACK16, VK_FORMAT_B5G6R5_UNORM_PACK16, + VK_FORMAT_R5G5B5A1_UNORM_PACK16, + VK_FORMAT_B5G5R5A1_UNORM_PACK16, VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_FORMAT_A2B10G10R10_UINT_PACK32, VK_FORMAT_A1R5G5B5_UNORM_PACK16, @@ -158,7 +169,9 @@ std::unordered_map<VkFormat, VkFormatProperties> GetFormatProperties(vk::Physica VK_FORMAT_R16G16B16A16_SFLOAT, VK_FORMAT_B8G8R8A8_UNORM, VK_FORMAT_B8G8R8A8_SRGB, + VK_FORMAT_R4G4_UNORM_PACK8, VK_FORMAT_R4G4B4A4_UNORM_PACK16, + VK_FORMAT_B4G4R4A4_UNORM_PACK16, VK_FORMAT_D32_SFLOAT, VK_FORMAT_D16_UNORM, VK_FORMAT_S8_UINT, @@ -596,6 +609,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR } logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); + is_integrated = properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU; + is_virtual = properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU; + is_non_gpu = properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_OTHER || + properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_CPU; + CollectPhysicalMemoryInfo(); CollectTelemetryParameters(); CollectToolingInfo(); @@ -614,6 +632,11 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR khr_push_descriptor = false; break; } + const u32 nv_major_version = (properties.driverVersion >> 22) & 0x3ff; + if (nv_major_version >= 510) { + LOG_WARNING(Render_Vulkan, "NVIDIA Drivers >= 510 do not support MSAA image blits"); + cant_blit_msaa = true; + } } const bool is_radv = driver_id == VK_DRIVER_ID_MESA_RADV; if (ext_extended_dynamic_state && is_radv) { @@ -724,7 +747,7 @@ VkFormat Device::GetSupportedFormat(VkFormat wanted_format, VkFormatFeatureFlags } void Device::ReportLoss() const { - LOG_CRITICAL(Render_Vulkan, "Device loss occured!"); + LOG_CRITICAL(Render_Vulkan, "Device loss occurred!"); // Wait for the log to flush and for Nsight Aftermath to dump the results std::this_thread::sleep_for(std::chrono::seconds{15}); @@ -985,6 +1008,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { test(has_khr_swapchain_mutable_format, VK_KHR_SWAPCHAIN_MUTABLE_FORMAT_EXTENSION_NAME, false); test(has_ext_line_rasterization, VK_EXT_LINE_RASTERIZATION_EXTENSION_NAME, false); + test(ext_memory_budget, VK_EXT_MEMORY_BUDGET_EXTENSION_NAME, true); if (Settings::values.enable_nsight_aftermath) { test(nv_device_diagnostics_config, VK_NV_DEVICE_DIAGNOSTICS_CONFIG_EXTENSION_NAME, true); @@ -997,7 +1021,7 @@ std::vector<const char*> Device::LoadExtensions(bool requires_surface) { VkPhysicalDeviceFeatures2KHR features{}; features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2_KHR; - VkPhysicalDeviceProperties2KHR physical_properties; + VkPhysicalDeviceProperties2KHR physical_properties{}; physical_properties.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2_KHR; if (has_khr_shader_float16_int8) { @@ -1267,15 +1291,50 @@ void Device::CollectTelemetryParameters() { vendor_name = driver.driverName; } +u64 Device::GetDeviceMemoryUsage() const { + VkPhysicalDeviceMemoryBudgetPropertiesEXT budget; + budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + budget.pNext = nullptr; + physical.GetMemoryProperties(&budget); + u64 result{}; + for (const size_t heap : valid_heap_memory) { + result += budget.heapUsage[heap]; + } + return result; +} + void Device::CollectPhysicalMemoryInfo() { - const auto mem_properties = physical.GetMemoryProperties(); + VkPhysicalDeviceMemoryBudgetPropertiesEXT budget{}; + budget.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_MEMORY_BUDGET_PROPERTIES_EXT; + const auto mem_info = physical.GetMemoryProperties(ext_memory_budget ? &budget : nullptr); + const auto& mem_properties = mem_info.memoryProperties; const size_t num_properties = mem_properties.memoryHeapCount; device_access_memory = 0; + u64 device_initial_usage = 0; + u64 local_memory = 0; for (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; + const bool is_heap_local = + (mem_properties.memoryHeaps[element].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) != 0; + if (!is_integrated && !is_heap_local) { + continue; } + valid_heap_memory.push_back(element); + if (is_heap_local) { + local_memory += mem_properties.memoryHeaps[element].size; + } + if (ext_memory_budget) { + device_initial_usage += budget.heapUsage[element]; + device_access_memory += budget.heapBudget[element]; + continue; + } + device_access_memory += mem_properties.memoryHeaps[element].size; + } + if (!is_integrated) { + return; } + const s64 available_memory = static_cast<s64>(device_access_memory - device_initial_usage); + device_access_memory = static_cast<u64>(std::max<s64>( + std::min<s64>(available_memory - 8_GiB, 4_GiB), static_cast<s64>(local_memory))); } void Device::CollectToolingInfo() { |