From 2f0b2f9839a3919cb425866f113a2a7bde2f85b7 Mon Sep 17 00:00:00 2001 From: Jugurta <74503778+i0x404@users.noreply.github.com> Date: Sun, 25 Aug 2024 09:27:04 +0100 Subject: [PATCH] Refactor Vulkan stream buffer memory type selection (#238) * Refactor Vulkan stream buffer memory type selection This is a fix for GPUs with Vulkan V1.1 and V1.2 * add requested refactoring * clang format * fix typo --- .../renderer_vulkan/vk_stream_buffer.cpp | 32 ++++++++++++++++--- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index 2a5bf7b0a..a12ab53e1 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp @@ -47,19 +47,41 @@ vk::MemoryPropertyFlags MakePropertyFlags(BufferType type) { /// Get the preferred host visible memory type. u32 GetMemoryType(const vk::PhysicalDeviceMemoryProperties& properties, BufferType type) { vk::MemoryPropertyFlags flags = MakePropertyFlags(type); - std::optional preferred_type = FindMemoryType(properties, flags); + std::optional preferred_type; + // Try to find a memory type with all the requested flags + preferred_type = FindMemoryType(properties, flags); + if (preferred_type) { + return *preferred_type; + } + + // If not found, try removing flags one by one constexpr std::array remove_flags = { + vk::MemoryPropertyFlagBits::eDeviceLocal, vk::MemoryPropertyFlagBits::eHostCached, vk::MemoryPropertyFlagBits::eHostCoherent, }; - for (u32 i = 0; i < remove_flags.size() && !preferred_type; i++) { - flags &= ~remove_flags[i]; + for (auto remove_flag : remove_flags) { + if ((flags & remove_flag) == vk::MemoryPropertyFlags{}) { + continue; + } + flags &= ~remove_flag; preferred_type = FindMemoryType(properties, flags); + if (preferred_type) { + return *preferred_type; + } } - ASSERT_MSG(preferred_type, "No suitable memory type found"); - return preferred_type.value(); + + // If still not found, try with only eHostVisible flag + preferred_type = FindMemoryType(properties, vk::MemoryPropertyFlagBits::eHostVisible); + if (preferred_type) { + return *preferred_type; + } + + // If we reach here, we couldn't find any suitable memory type + UNREACHABLE_MSG("Failed to find a suitable memory type for buffer type {}", + BufferTypeName(type)); } constexpr u64 WATCHES_INITIAL_RESERVE = 0x4000;