diff options
-rw-r--r-- | src/common/common_funcs.h | 16 | ||||
-rw-r--r-- | src/core/hle/service/filesystem/filesystem.cpp | 5 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_descriptor_pool.cpp | 6 | ||||
-rw-r--r-- | src/video_core/renderer_vulkan/vk_rasterizer.cpp | 14 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.cpp | 34 | ||||
-rw-r--r-- | src/video_core/vulkan_common/vulkan_device.h | 5 |
6 files changed, 70 insertions, 10 deletions
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 1e74d6930..4c1e29de6 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -61,6 +61,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void); using T = std::underlying_type_t<type>; \ return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \ } \ + [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \ + using T = std::underlying_type_t<type>; \ + return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \ + } \ + [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \ + using T = std::underlying_type_t<type>; \ + return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \ + } \ constexpr type& operator|=(type& a, type b) noexcept { \ a = a | b; \ return a; \ @@ -73,6 +81,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void); a = a ^ b; \ return a; \ } \ + constexpr type& operator<<=(type& a, type b) noexcept { \ + a = a << b; \ + return a; \ + } \ + constexpr type& operator>>=(type& a, type b) noexcept { \ + a = a >> b; \ + return a; \ + } \ [[nodiscard]] constexpr type operator~(type key) noexcept { \ using T = std::underlying_type_t<type>; \ return static_cast<type>(~static_cast<T>(key)); \ diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index db17d61e4..c8d65f328 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -97,6 +97,11 @@ ResultCode VfsDirectoryServiceWrapper::DeleteFile(const std::string& path_) cons ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const { std::string path(Common::FS::SanitizePath(path_)); + + // NOTE: This is inaccurate behavior. CreateDirectory is not recursive. + // CreateDirectory should return PathNotFound if the parent directory does not exist. + // This is here temporarily in order to have UMM "work" in the meantime. + // TODO (Morph): Remove this when a hardware test verifies the correct behavior. const auto components = Common::FS::SplitPathComponents(path); std::string relative_path; for (const auto& component : components) { diff --git a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp index adb557f60..d87da2a34 100644 --- a/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp +++ b/src/video_core/renderer_vulkan/vk_descriptor_pool.cpp @@ -19,7 +19,6 @@ namespace Vulkan { // Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines constexpr size_t SETS_GROW_RATE = 16; constexpr s32 SCORE_THRESHOLD = 3; -constexpr u32 SETS_PER_POOL = 64; struct DescriptorBank { DescriptorBankInfo info; @@ -59,11 +58,12 @@ static DescriptorBankInfo MakeBankInfo(std::span<const Shader::Info> infos) { static void AllocatePool(const Device& device, DescriptorBank& bank) { std::array<VkDescriptorPoolSize, 6> pool_sizes; size_t pool_cursor{}; + const u32 sets_per_pool = device.GetSetsPerPool(); const auto add = [&](VkDescriptorType type, u32 count) { if (count > 0) { pool_sizes[pool_cursor++] = { .type = type, - .descriptorCount = count * SETS_PER_POOL, + .descriptorCount = count * sets_per_pool, }; } }; @@ -78,7 +78,7 @@ static void AllocatePool(const Device& device, DescriptorBank& bank) { .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, .pNext = nullptr, .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, - .maxSets = SETS_PER_POOL, + .maxSets = sets_per_pool, .poolSizeCount = static_cast<u32>(pool_cursor), .pPoolSizes = std::data(pool_sizes), })); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 841a6b846..3bcd6d6cc 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -765,12 +765,7 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass; const Maxwell::ComparisonOp compare = regs.stencil_front_func_func; if (regs.stencil_two_side_enable) { - scheduler.Record([fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf) { - cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), - MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), - MaxwellToVK::ComparisonOp(compare)); - }); - } else { + // Separate stencil op per face const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail; const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail; const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass; @@ -785,6 +780,13 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { MaxwellToVK::StencilOp(back_zfail), MaxwellToVK::ComparisonOp(back_compare)); }); + } else { + // Front face defines the stencil op of both faces + scheduler.Record([fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf) { + cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), + MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), + MaxwellToVK::ComparisonOp(compare)); + }); } } diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp index 24821c1a3..24fb50db9 100644 --- a/src/video_core/vulkan_common/vulkan_device.cpp +++ b/src/video_core/vulkan_common/vulkan_device.cpp @@ -243,6 +243,7 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR SetupFamilies(surface); SetupFeatures(); SetupProperties(); + CollectTelemetryParameters(); const auto queue_cis = GetDeviceQueueCreateInfos(); const std::vector extensions = LoadExtensions(surface != nullptr); @@ -368,6 +369,18 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR }; SetNext(next, demote); + if (driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE) { + const u32 version = properties.driverVersion; + // Broken in this driver + if (version > VK_MAKE_API_VERSION(0, 2, 0, 193)) { + LOG_WARNING(Render_Vulkan, "AMD proprietary driver versions newer than 21.9.1 " + "(windows) / 0.2.0.194 (amdvlk) have " + "broken VkPhysicalDeviceFloat16Int8FeaturesKHR"); + is_int8_supported = false; + is_float16_supported = false; + } + } + if (is_int8_supported || is_float16_supported) { VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8{ .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, @@ -560,7 +573,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); CollectPhysicalMemoryInfo(); - CollectTelemetryParameters(); CollectToolingInfo(); if (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { @@ -587,6 +599,26 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR ext_extended_dynamic_state = false; } } + + sets_per_pool = 64; + if (driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE) { + // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. + sets_per_pool = 96; + } + + const bool is_amd = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || + driver_id == VK_DRIVER_ID_MESA_RADV || + driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; + if (ext_sampler_filter_minmax && is_amd) { + // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken. + if (!is_float16_supported) { + LOG_WARNING( + Render_Vulkan, + "Blacklisting AMD GCN4 and lower for VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME"); + ext_sampler_filter_minmax = false; + } + } + if (ext_vertex_input_dynamic_state && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state"); ext_vertex_input_dynamic_state = false; diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h index 5599c38c5..bc180a32a 100644 --- a/src/video_core/vulkan_common/vulkan_device.h +++ b/src/video_core/vulkan_common/vulkan_device.h @@ -323,6 +323,10 @@ public: return device_access_memory; } + u32 GetSetsPerPool() const { + return sets_per_pool; + } + private: /// Checks if the physical device is suitable. void CheckSuitability(bool requires_swapchain) const; @@ -376,6 +380,7 @@ private: VkShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced. u64 device_access_memory{}; ///< Total size of device local memory in bytes. u32 max_push_descriptors{}; ///< Maximum number of push descriptors + u32 sets_per_pool{}; ///< Sets per Description Pool bool is_optimal_astc_supported{}; ///< Support for native ASTC. bool is_float16_supported{}; ///< Support for float16 arithmetic. bool is_int8_supported{}; ///< Support for int8 arithmetic. |