diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/common/settings_common.cpp | 2 | ||||
-rw-r--r-- | src/common/settings_enums.h | 16 | ||||
-rw-r--r-- | src/common/settings_setting.h | 10 | ||||
-rw-r--r-- | src/core/hle/service/ssl/ssl_backend_securetransport.cpp | 2 | ||||
-rw-r--r-- | src/core/memory.h | 125 | ||||
-rw-r--r-- | src/video_core/engines/maxwell_dma.cpp | 1 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 179 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 9 | ||||
-rw-r--r-- | src/yuzu/game_list.cpp | 8 |
9 files changed, 202 insertions, 150 deletions
diff --git a/src/common/settings_common.cpp b/src/common/settings_common.cpp index dedf5ef90..137b65d5f 100644 --- a/src/common/settings_common.cpp +++ b/src/common/settings_common.cpp @@ -1,7 +1,9 @@ // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <functional> #include <string> +#include <vector> #include "common/settings_common.h" namespace Settings { diff --git a/src/common/settings_enums.h b/src/common/settings_enums.h index a1a29ebf6..e7cb59ea5 100644 --- a/src/common/settings_enums.h +++ b/src/common/settings_enums.h @@ -12,8 +12,8 @@ namespace Settings { template <typename T> struct EnumMetadata { - static constexpr std::vector<std::pair<std::string, T>> Canonicalizations(); - static constexpr u32 Index(); + static std::vector<std::pair<std::string, T>> Canonicalizations(); + static u32 Index(); }; #define PAIR_45(N, X, ...) {#X, N::X} __VA_OPT__(, PAIR_46(N, __VA_ARGS__)) @@ -66,11 +66,11 @@ struct EnumMetadata { #define ENUM(NAME, ...) \ enum class NAME : u32 { __VA_ARGS__ }; \ template <> \ - constexpr std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \ + inline std::vector<std::pair<std::string, NAME>> EnumMetadata<NAME>::Canonicalizations() { \ return {PAIR(NAME, __VA_ARGS__)}; \ } \ template <> \ - constexpr u32 EnumMetadata<NAME>::Index() { \ + inline u32 EnumMetadata<NAME>::Index() { \ return __COUNTER__; \ } @@ -85,7 +85,7 @@ enum class AudioEngine : u32 { }; template <> -constexpr std::vector<std::pair<std::string, AudioEngine>> +inline std::vector<std::pair<std::string, AudioEngine>> EnumMetadata<AudioEngine>::Canonicalizations() { return { {"auto", AudioEngine::Auto}, @@ -96,7 +96,7 @@ EnumMetadata<AudioEngine>::Canonicalizations() { } template <> -constexpr u32 EnumMetadata<AudioEngine>::Index() { +inline u32 EnumMetadata<AudioEngine>::Index() { // This is just a sufficiently large number that is more than the number of other enums declared // here return 100; @@ -147,7 +147,7 @@ ENUM(AntiAliasing, None, Fxaa, Smaa, MaxEnum); ENUM(AspectRatio, R16_9, R4_3, R21_9, R16_10, Stretch); template <typename Type> -constexpr std::string CanonicalizeEnum(Type id) { +inline std::string CanonicalizeEnum(Type id) { const auto group = EnumMetadata<Type>::Canonicalizations(); for (auto& [name, value] : group) { if (value == id) { @@ -158,7 +158,7 @@ constexpr std::string CanonicalizeEnum(Type id) { } template <typename Type> -constexpr Type ToEnum(const std::string& canonicalization) { +inline Type ToEnum(const std::string& canonicalization) { const auto group = EnumMetadata<Type>::Canonicalizations(); for (auto& [name, value] : group) { if (name == canonicalization) { diff --git a/src/common/settings_setting.h b/src/common/settings_setting.h index a8beb06e9..e10843c73 100644 --- a/src/common/settings_setting.h +++ b/src/common/settings_setting.h @@ -190,7 +190,7 @@ public: } } - [[nodiscard]] std::string constexpr Canonicalize() const override final { + [[nodiscard]] std::string Canonicalize() const override final { if constexpr (std::is_enum_v<Type>) { return CanonicalizeEnum(this->GetValue()); } else { @@ -256,11 +256,11 @@ public: * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded * @param other_setting_ A second Setting to associate to this one in metadata */ + template <typename T = BasicSetting> explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, - BasicSetting* other_setting_ = nullptr) - requires(!ranged) + typename std::enable_if<!ranged, T*>::type other_setting_ = nullptr) : Setting<Type, false>{ linkage, default_val, name, category_, specialization_, save_, runtime_modifiable_, other_setting_} { @@ -282,12 +282,12 @@ public: * @param runtime_modifiable_ Suggests whether this is modifiable while a guest is loaded * @param other_setting_ A second Setting to associate to this one in metadata */ + template <typename T = BasicSetting> explicit SwitchableSetting(Linkage& linkage, const Type& default_val, const Type& min_val, const Type& max_val, const std::string& name, Category category_, u32 specialization_ = Specialization::Default, bool save_ = true, bool runtime_modifiable_ = false, - BasicSetting* other_setting_ = nullptr) - requires(ranged) + typename std::enable_if<ranged, T*>::type other_setting_ = nullptr) : Setting<Type, true>{linkage, default_val, min_val, max_val, name, category_, specialization_, save_, runtime_modifiable_, diff --git a/src/core/hle/service/ssl/ssl_backend_securetransport.cpp b/src/core/hle/service/ssl/ssl_backend_securetransport.cpp index 370678f48..c48914f64 100644 --- a/src/core/hle/service/ssl/ssl_backend_securetransport.cpp +++ b/src/core/hle/service/ssl/ssl_backend_securetransport.cpp @@ -100,7 +100,7 @@ public: Result DoHandshake() override { OSStatus status = SSLHandshake(context); - return HandleReturn("SSLHandshake", 0, status).Code(); + return HandleReturn("SSLHandshake", 0, status); } Result Read(size_t* out_size, std::span<u8> data) override { diff --git a/src/core/memory.h b/src/core/memory.h index 2eb61ffd3..13047a545 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -509,9 +509,9 @@ class GuestMemory { public: GuestMemory() = delete; - explicit GuestMemory(M& memory_, u64 addr_, std::size_t size_, + explicit GuestMemory(M& memory, u64 addr, std::size_t size, Common::ScratchBuffer<T>* backup = nullptr) - : memory{memory_}, addr{addr_}, size{size_} { + : m_memory{memory}, m_addr{addr}, m_size{size} { static_assert(FLAGS & GuestMemoryFlags::Read || FLAGS & GuestMemoryFlags::Write); if constexpr (FLAGS & GuestMemoryFlags::Read) { Read(addr, size, backup); @@ -521,89 +521,97 @@ public: ~GuestMemory() = default; T* data() noexcept { - return data_span.data(); + return m_data_span.data(); } const T* data() const noexcept { - return data_span.data(); + return m_data_span.data(); + } + + size_t size() const noexcept { + return m_size; + } + + size_t size_bytes() const noexcept { + return this->size() * sizeof(T); } [[nodiscard]] T* begin() noexcept { - return data(); + return this->data(); } [[nodiscard]] const T* begin() const noexcept { - return data(); + return this->data(); } [[nodiscard]] T* end() noexcept { - return data() + size; + return this->data() + this->size(); } [[nodiscard]] const T* end() const noexcept { - return data() + size; + return this->data() + this->size(); } T& operator[](size_t index) noexcept { - return data_span[index]; + return m_data_span[index]; } const T& operator[](size_t index) const noexcept { - return data_span[index]; + return m_data_span[index]; } - void SetAddressAndSize(u64 addr_, std::size_t size_) noexcept { - addr = addr_; - size = size_; - addr_changed = true; + void SetAddressAndSize(u64 addr, std::size_t size) noexcept { + m_addr = addr; + m_size = size; + m_addr_changed = true; } - std::span<T> Read(u64 addr_, std::size_t size_, + std::span<T> Read(u64 addr, std::size_t size, Common::ScratchBuffer<T>* backup = nullptr) noexcept { - addr = addr_; - size = size_; - if (size == 0) { - is_data_copy = true; + m_addr = addr; + m_size = size; + if (m_size == 0) { + m_is_data_copy = true; return {}; } - if (TrySetSpan()) { + if (this->TrySetSpan()) { if constexpr (FLAGS & GuestMemoryFlags::Safe) { - memory.FlushRegion(addr, size * sizeof(T)); + m_memory.FlushRegion(m_addr, this->size_bytes()); } } else { if (backup) { - backup->resize_destructive(size); - data_span = *backup; + backup->resize_destructive(this->size()); + m_data_span = *backup; } else { - data_copy.resize(size); - data_span = std::span(data_copy); + m_data_copy.resize(this->size()); + m_data_span = std::span(m_data_copy); } - is_data_copy = true; - span_valid = true; + m_is_data_copy = true; + m_span_valid = true; if constexpr (FLAGS & GuestMemoryFlags::Safe) { - memory.ReadBlock(addr, data_span.data(), size * sizeof(T)); + m_memory.ReadBlock(m_addr, this->data(), this->size_bytes()); } else { - memory.ReadBlockUnsafe(addr, data_span.data(), size * sizeof(T)); + m_memory.ReadBlockUnsafe(m_addr, this->data(), this->size_bytes()); } } - return data_span; + return m_data_span; } void Write(std::span<T> write_data) noexcept { if constexpr (FLAGS & GuestMemoryFlags::Cached) { - memory.WriteBlockCached(addr, write_data.data(), size * sizeof(T)); + m_memory.WriteBlockCached(m_addr, write_data.data(), this->size_bytes()); } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { - memory.WriteBlock(addr, write_data.data(), size * sizeof(T)); + m_memory.WriteBlock(m_addr, write_data.data(), this->size_bytes()); } else { - memory.WriteBlockUnsafe(addr, write_data.data(), size * sizeof(T)); + m_memory.WriteBlockUnsafe(m_addr, write_data.data(), this->size_bytes()); } } bool TrySetSpan() noexcept { - if (u8* ptr = memory.GetSpan(addr, size * sizeof(T)); ptr) { - data_span = {reinterpret_cast<T*>(ptr), size}; - span_valid = true; + if (u8* ptr = m_memory.GetSpan(m_addr, this->size_bytes()); ptr) { + m_data_span = {reinterpret_cast<T*>(ptr), this->size()}; + m_span_valid = true; return true; } return false; @@ -611,36 +619,36 @@ public: protected: bool IsDataCopy() const noexcept { - return is_data_copy; + return m_is_data_copy; } bool AddressChanged() const noexcept { - return addr_changed; + return m_addr_changed; } - M& memory; - u64 addr; - size_t size; - std::span<T> data_span{}; - std::vector<T> data_copy; - bool span_valid{false}; - bool is_data_copy{false}; - bool addr_changed{false}; + M& m_memory; + u64 m_addr{}; + size_t m_size{}; + std::span<T> m_data_span{}; + std::vector<T> m_data_copy{}; + bool m_span_valid{false}; + bool m_is_data_copy{false}; + bool m_addr_changed{false}; }; template <typename M, typename T, GuestMemoryFlags FLAGS> class GuestMemoryScoped : public GuestMemory<M, T, FLAGS> { public: GuestMemoryScoped() = delete; - explicit GuestMemoryScoped(M& memory_, u64 addr_, std::size_t size_, + explicit GuestMemoryScoped(M& memory, u64 addr, std::size_t size, Common::ScratchBuffer<T>* backup = nullptr) - : GuestMemory<M, T, FLAGS>(memory_, addr_, size_, backup) { + : GuestMemory<M, T, FLAGS>(memory, addr, size, backup) { if constexpr (!(FLAGS & GuestMemoryFlags::Read)) { if (!this->TrySetSpan()) { if (backup) { - this->data_span = *backup; - this->span_valid = true; - this->is_data_copy = true; + this->m_data_span = *backup; + this->m_span_valid = true; + this->m_is_data_copy = true; } } } @@ -648,24 +656,21 @@ public: ~GuestMemoryScoped() { if constexpr (FLAGS & GuestMemoryFlags::Write) { - if (this->size == 0) [[unlikely]] { + if (this->size() == 0) [[unlikely]] { return; } if (this->AddressChanged() || this->IsDataCopy()) { - ASSERT(this->span_valid); + ASSERT(this->m_span_valid); if constexpr (FLAGS & GuestMemoryFlags::Cached) { - this->memory.WriteBlockCached(this->addr, this->data_span.data(), - this->size * sizeof(T)); + this->m_memory.WriteBlockCached(this->m_addr, this->data(), this->size_bytes()); } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { - this->memory.WriteBlock(this->addr, this->data_span.data(), - this->size * sizeof(T)); + this->m_memory.WriteBlock(this->m_addr, this->data(), this->size_bytes()); } else { - this->memory.WriteBlockUnsafe(this->addr, this->data_span.data(), - this->size * sizeof(T)); + this->m_memory.WriteBlockUnsafe(this->m_addr, this->data(), this->size_bytes()); } } else if constexpr (FLAGS & GuestMemoryFlags::Safe) { - this->memory.InvalidateRegion(this->addr, this->size * sizeof(T)); + this->m_memory.InvalidateRegion(this->m_addr, this->size_bytes()); } } } diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp index cd8e24b0b..da8eab7ee 100644 --- a/src/video_core/engines/maxwell_dma.cpp +++ b/src/video_core/engines/maxwell_dma.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "common/microprofile.h" +#include "common/polyfill_ranges.h" #include "common/settings.h" #include "core/core.h" #include "core/memory.h" diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 710929ac5..adde96aa5 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -326,6 +326,43 @@ std::vector<const char*> ExtensionListForVulkan( } // Anonymous namespace +void Device::RemoveExtension(bool& extension, const std::string& extension_name) { + extension = false; + loaded_extensions.erase(extension_name); +} + +void Device::RemoveExtensionIfUnsuitable(bool is_suitable, const std::string& extension_name) { + if (loaded_extensions.contains(extension_name) && !is_suitable) { + LOG_WARNING(Render_Vulkan, "Removing unsuitable extension {}", extension_name); + this->RemoveExtension(is_suitable, extension_name); + } +} + +template <typename Feature> +void Device::RemoveExtensionFeature(bool& extension, Feature& feature, + const std::string& extension_name) { + // Unload extension. + this->RemoveExtension(extension, extension_name); + + // Save sType and pNext for chain. + VkStructureType sType = feature.sType; + void* pNext = feature.pNext; + + // Clear feature struct and restore chain. + feature = {}; + feature.sType = sType; + feature.pNext = pNext; +} + +template <typename Feature> +void Device::RemoveExtensionFeatureIfUnsuitable(bool is_suitable, Feature& feature, + const std::string& extension_name) { + if (loaded_extensions.contains(extension_name) && !is_suitable) { + LOG_WARNING(Render_Vulkan, "Removing features for unsuitable extension {}", extension_name); + this->RemoveExtensionFeature(is_suitable, feature, extension_name); + } +} + Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR surface, const vk::InstanceDispatch& dld_) : instance{instance_}, dld{dld_}, physical{physical_}, @@ -397,21 +434,20 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_qualcomm || is_turnip) { LOG_WARNING(Render_Vulkan, "Qualcomm and Turnip drivers have broken VK_EXT_custom_border_color"); - extensions.custom_border_color = false; - loaded_extensions.erase(VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + RemoveExtensionFeature(extensions.custom_border_color, features.custom_border_color, + VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); } if (is_qualcomm) { must_emulate_scaled_formats = true; LOG_WARNING(Render_Vulkan, "Qualcomm drivers have broken VK_EXT_extended_dynamic_state"); - extensions.extended_dynamic_state = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); LOG_WARNING(Render_Vulkan, "Qualcomm drivers have a slow VK_KHR_push_descriptor implementation"); - extensions.push_descriptor = false; - loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); #if defined(ANDROID) && defined(ARCHITECTURE_arm64) // Patch the driver to enable BCn textures. @@ -440,15 +476,12 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR must_emulate_scaled_formats = true; LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state"); - extensions.extended_dynamic_state = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state, features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); LOG_WARNING(Render_Vulkan, "ARM drivers have broken VK_EXT_extended_dynamic_state2"); - features.extended_dynamic_state2.extendedDynamicState2 = false; - features.extended_dynamic_state2.extendedDynamicState2LogicOp = false; - features.extended_dynamic_state2.extendedDynamicState2PatchControlPoints = false; - extensions.extended_dynamic_state2 = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state2, features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } if (is_nvidia) { @@ -464,8 +497,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR case NvidiaArchitecture::VoltaOrOlder: if (nv_major_version < 527) { LOG_WARNING(Render_Vulkan, "Volta and older have broken VK_KHR_push_descriptor"); - extensions.push_descriptor = false; - loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } break; } @@ -480,8 +512,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (version < VK_MAKE_API_VERSION(0, 21, 2, 0)) { LOG_WARNING(Render_Vulkan, "RADV versions older than 21.2 have broken VK_EXT_extended_dynamic_state"); - extensions.extended_dynamic_state = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state, + features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_radv) { @@ -490,11 +523,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING( Render_Vulkan, "RADV versions older than 22.3.1 have broken VK_EXT_extended_dynamic_state2"); - features.extended_dynamic_state2.extendedDynamicState2 = false; - features.extended_dynamic_state2.extendedDynamicState2LogicOp = false; - features.extended_dynamic_state2.extendedDynamicState2PatchControlPoints = false; - extensions.extended_dynamic_state2 = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state2 && is_qualcomm) { @@ -504,11 +535,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // Qualcomm Adreno 7xx drivers do not properly support extended_dynamic_state2. LOG_WARNING(Render_Vulkan, "Qualcomm Adreno 7xx drivers have broken VK_EXT_extended_dynamic_state2"); - features.extended_dynamic_state2.extendedDynamicState2 = false; - features.extended_dynamic_state2.extendedDynamicState2LogicOp = false; - features.extended_dynamic_state2.extendedDynamicState2PatchControlPoints = false; - extensions.extended_dynamic_state2 = false; - loaded_extensions.erase(VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeature(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); } } if (extensions.extended_dynamic_state3 && is_radv) { @@ -540,9 +569,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (is_rdna2) { LOG_WARNING(Render_Vulkan, "RADV has broken VK_EXT_vertex_input_dynamic_state on RDNA2 hardware"); - features.vertex_input_dynamic_state.vertexInputDynamicState = false; - extensions.vertex_input_dynamic_state = false; - loaded_extensions.erase(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (extensions.vertex_input_dynamic_state && is_qualcomm) { @@ -553,9 +582,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR LOG_WARNING( Render_Vulkan, "Qualcomm Adreno 7xx drivers have broken VK_EXT_vertex_input_dynamic_state"); - features.vertex_input_dynamic_state.vertexInputDynamicState = false; - extensions.vertex_input_dynamic_state = false; - loaded_extensions.erase(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } @@ -575,8 +604,8 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR if (!features.shader_float16_int8.shaderFloat16) { LOG_WARNING(Render_Vulkan, "AMD GCN4 and earlier have broken VK_EXT_sampler_filter_minmax"); - extensions.sampler_filter_minmax = false; - loaded_extensions.erase(VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); + RemoveExtension(extensions.sampler_filter_minmax, + VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME); } } @@ -584,8 +613,9 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR const u32 version = (properties.properties.driverVersion << 3) >> 3; if (version < VK_MAKE_API_VERSION(27, 20, 100, 0)) { LOG_WARNING(Render_Vulkan, "Intel has broken VK_EXT_vertex_input_dynamic_state"); - extensions.vertex_input_dynamic_state = false; - loaded_extensions.erase(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeature(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); } } if (features.shader_float16_int8.shaderFloat16 && is_intel_windows) { @@ -612,8 +642,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR // mesa/mesa/-/commit/ff91c5ca42bc80aa411cb3fd8f550aa6fdd16bdc LOG_WARNING(Render_Vulkan, "ANV drivers 22.3.0 to 23.1.0 have broken VK_KHR_push_descriptor"); - extensions.push_descriptor = false; - loaded_extensions.erase(VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); + RemoveExtension(extensions.push_descriptor, VK_KHR_PUSH_DESCRIPTOR_EXTENSION_NAME); } } if (is_mvk) { @@ -1007,34 +1036,29 @@ bool Device::GetSuitability(bool requires_swapchain) { return suitable; } -void Device::RemoveExtensionIfUnsuitable(bool is_suitable, const std::string& extension_name) { - if (loaded_extensions.contains(extension_name) && !is_suitable) { - LOG_WARNING(Render_Vulkan, "Removing unsuitable extension {}", extension_name); - loaded_extensions.erase(extension_name); - } -} - void Device::RemoveUnsuitableExtensions() { // VK_EXT_custom_border_color extensions.custom_border_color = features.custom_border_color.customBorderColors && features.custom_border_color.customBorderColorWithoutFormat; - RemoveExtensionIfUnsuitable(extensions.custom_border_color, - VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.custom_border_color, features.custom_border_color, + VK_EXT_CUSTOM_BORDER_COLOR_EXTENSION_NAME); // VK_EXT_depth_clip_control extensions.depth_clip_control = features.depth_clip_control.depthClipControl; - RemoveExtensionIfUnsuitable(extensions.depth_clip_control, - VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.depth_clip_control, features.depth_clip_control, + VK_EXT_DEPTH_CLIP_CONTROL_EXTENSION_NAME); // VK_EXT_extended_dynamic_state extensions.extended_dynamic_state = features.extended_dynamic_state.extendedDynamicState; - RemoveExtensionIfUnsuitable(extensions.extended_dynamic_state, - VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state, + features.extended_dynamic_state, + VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); // VK_EXT_extended_dynamic_state2 extensions.extended_dynamic_state2 = features.extended_dynamic_state2.extendedDynamicState2; - RemoveExtensionIfUnsuitable(extensions.extended_dynamic_state2, - VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state2, + features.extended_dynamic_state2, + VK_EXT_EXTENDED_DYNAMIC_STATE_2_EXTENSION_NAME); // VK_EXT_extended_dynamic_state3 dynamic_state3_blending = @@ -1048,35 +1072,38 @@ void Device::RemoveUnsuitableExtensions() { extensions.extended_dynamic_state3 = dynamic_state3_blending || dynamic_state3_enables; dynamic_state3_blending = dynamic_state3_blending && extensions.extended_dynamic_state3; dynamic_state3_enables = dynamic_state3_enables && extensions.extended_dynamic_state3; - RemoveExtensionIfUnsuitable(extensions.extended_dynamic_state3, - VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.extended_dynamic_state3, + features.extended_dynamic_state3, + VK_EXT_EXTENDED_DYNAMIC_STATE_3_EXTENSION_NAME); // VK_EXT_provoking_vertex extensions.provoking_vertex = features.provoking_vertex.provokingVertexLast && features.provoking_vertex.transformFeedbackPreservesProvokingVertex; - RemoveExtensionIfUnsuitable(extensions.provoking_vertex, - VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.provoking_vertex, features.provoking_vertex, + VK_EXT_PROVOKING_VERTEX_EXTENSION_NAME); // VK_KHR_shader_atomic_int64 extensions.shader_atomic_int64 = features.shader_atomic_int64.shaderBufferInt64Atomics && features.shader_atomic_int64.shaderSharedInt64Atomics; - RemoveExtensionIfUnsuitable(extensions.shader_atomic_int64, - VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.shader_atomic_int64, features.shader_atomic_int64, + VK_KHR_SHADER_ATOMIC_INT64_EXTENSION_NAME); // VK_EXT_shader_demote_to_helper_invocation extensions.shader_demote_to_helper_invocation = features.shader_demote_to_helper_invocation.shaderDemoteToHelperInvocation; - RemoveExtensionIfUnsuitable(extensions.shader_demote_to_helper_invocation, - VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.shader_demote_to_helper_invocation, + features.shader_demote_to_helper_invocation, + VK_EXT_SHADER_DEMOTE_TO_HELPER_INVOCATION_EXTENSION_NAME); // VK_EXT_subgroup_size_control extensions.subgroup_size_control = features.subgroup_size_control.subgroupSizeControl && properties.subgroup_size_control.minSubgroupSize <= GuestWarpSize && properties.subgroup_size_control.maxSubgroupSize >= GuestWarpSize; - RemoveExtensionIfUnsuitable(extensions.subgroup_size_control, - VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.subgroup_size_control, + features.subgroup_size_control, + VK_EXT_SUBGROUP_SIZE_CONTROL_EXTENSION_NAME); // VK_EXT_transform_feedback extensions.transform_feedback = @@ -1086,24 +1113,27 @@ void Device::RemoveUnsuitableExtensions() { properties.transform_feedback.maxTransformFeedbackBuffers > 0 && properties.transform_feedback.transformFeedbackQueries && properties.transform_feedback.transformFeedbackDraw; - RemoveExtensionIfUnsuitable(extensions.transform_feedback, - VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.transform_feedback, features.transform_feedback, + VK_EXT_TRANSFORM_FEEDBACK_EXTENSION_NAME); // VK_EXT_vertex_input_dynamic_state extensions.vertex_input_dynamic_state = features.vertex_input_dynamic_state.vertexInputDynamicState; - RemoveExtensionIfUnsuitable(extensions.vertex_input_dynamic_state, - VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.vertex_input_dynamic_state, + features.vertex_input_dynamic_state, + VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); // VK_KHR_pipeline_executable_properties if (Settings::values.renderer_shader_feedback.GetValue()) { extensions.pipeline_executable_properties = features.pipeline_executable_properties.pipelineExecutableInfo; - RemoveExtensionIfUnsuitable(extensions.pipeline_executable_properties, - VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.pipeline_executable_properties, + features.pipeline_executable_properties, + VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); } else { - extensions.pipeline_executable_properties = false; - loaded_extensions.erase(VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); + RemoveExtensionFeature(extensions.pipeline_executable_properties, + features.pipeline_executable_properties, + VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); } // VK_KHR_workgroup_memory_explicit_layout @@ -1113,8 +1143,9 @@ void Device::RemoveUnsuitableExtensions() { features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout8BitAccess && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout16BitAccess && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayoutScalarBlockLayout; - RemoveExtensionIfUnsuitable(extensions.workgroup_memory_explicit_layout, - VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); + RemoveExtensionFeatureIfUnsuitable(extensions.workgroup_memory_explicit_layout, + features.workgroup_memory_explicit_layout, + VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); } void Device::SetupFamilies(VkSurfaceKHR surface) { diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index d8dd41e51..488fdd313 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -639,8 +639,17 @@ private: // Remove extensions which have incomplete feature support. void RemoveUnsuitableExtensions(); + + void RemoveExtension(bool& extension, const std::string& extension_name); void RemoveExtensionIfUnsuitable(bool is_suitable, const std::string& extension_name); + template <typename Feature> + void RemoveExtensionFeature(bool& extension, Feature& feature, + const std::string& extension_name); + template <typename Feature> + void RemoveExtensionFeatureIfUnsuitable(bool is_suitable, Feature& feature, + const std::string& extension_name); + /// Sets up queue families. void SetupFamilies(VkSurfaceKHR surface); diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 465084fea..b5a02700d 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -214,13 +214,17 @@ void GameList::OnTextChanged(const QString& new_text) { const int children_count = folder->rowCount(); for (int j = 0; j < children_count; ++j) { ++children_total; + const QStandardItem* child = folder->child(j, 0); + + const auto program_id = child->data(GameListItemPath::ProgramIdRole).toULongLong(); + const QString file_path = child->data(GameListItemPath::FullPathRole).toString().toLower(); const QString file_title = child->data(GameListItemPath::TitleRole).toString().toLower(); const QString file_program_id = - child->data(GameListItemPath::ProgramIdRole).toString().toLower(); + QStringLiteral("%1").arg(program_id, 16, 16, QLatin1Char{'0'}); // Only items which filename in combination with its title contains all words // that are in the searchfield will be visible in the gamelist @@ -231,7 +235,7 @@ void GameList::OnTextChanged(const QString& new_text) { file_path.mid(file_path.lastIndexOf(QLatin1Char{'/'}) + 1) + QLatin1Char{' '} + file_title; if (ContainsAllWords(file_name, edit_filter_text) || - (file_program_id.count() == 16 && edit_filter_text.contains(file_program_id))) { + (file_program_id.count() == 16 && file_program_id.contains(edit_filter_text))) { tree_view->setRowHidden(j, folder_index, false); ++result_count; } else { |