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); | |||
| 61 | using T = std::underlying_type_t<type>; \ | 61 | using T = std::underlying_type_t<type>; \ |
| 62 | return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \ | 62 | return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \ |
| 63 | } \ | 63 | } \ |
| 64 | [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \ | ||
| 65 | using T = std::underlying_type_t<type>; \ | ||
| 66 | return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \ | ||
| 67 | } \ | ||
| 68 | [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \ | ||
| 69 | using T = std::underlying_type_t<type>; \ | ||
| 70 | return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \ | ||
| 71 | } \ | ||
| 64 | constexpr type& operator|=(type& a, type b) noexcept { \ | 72 | constexpr type& operator|=(type& a, type b) noexcept { \ |
| 65 | a = a | b; \ | 73 | a = a | b; \ |
| 66 | return a; \ | 74 | return a; \ |
| @@ -73,6 +81,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void); | |||
| 73 | a = a ^ b; \ | 81 | a = a ^ b; \ |
| 74 | return a; \ | 82 | return a; \ |
| 75 | } \ | 83 | } \ |
| 84 | constexpr type& operator<<=(type& a, type b) noexcept { \ | ||
| 85 | a = a << b; \ | ||
| 86 | return a; \ | ||
| 87 | } \ | ||
| 88 | constexpr type& operator>>=(type& a, type b) noexcept { \ | ||
| 89 | a = a >> b; \ | ||
| 90 | return a; \ | ||
| 91 | } \ | ||
| 76 | [[nodiscard]] constexpr type operator~(type key) noexcept { \ | 92 | [[nodiscard]] constexpr type operator~(type key) noexcept { \ |
| 77 | using T = std::underlying_type_t<type>; \ | 93 | using T = std::underlying_type_t<type>; \ |
| 78 | return static_cast<type>(~static_cast<T>(key)); \ | 94 | 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 | |||
| 97 | 97 | ||
| 98 | ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const { | 98 | ResultCode VfsDirectoryServiceWrapper::CreateDirectory(const std::string& path_) const { |
| 99 | std::string path(Common::FS::SanitizePath(path_)); | 99 | std::string path(Common::FS::SanitizePath(path_)); |
| 100 | |||
| 101 | // NOTE: This is inaccurate behavior. CreateDirectory is not recursive. | ||
| 102 | // CreateDirectory should return PathNotFound if the parent directory does not exist. | ||
| 103 | // This is here temporarily in order to have UMM "work" in the meantime. | ||
| 104 | // TODO (Morph): Remove this when a hardware test verifies the correct behavior. | ||
| 100 | const auto components = Common::FS::SplitPathComponents(path); | 105 | const auto components = Common::FS::SplitPathComponents(path); |
| 101 | std::string relative_path; | 106 | std::string relative_path; |
| 102 | for (const auto& component : components) { | 107 | 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 { | |||
| 19 | // Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines | 19 | // Prefer small grow rates to avoid saturating the descriptor pool with barely used pipelines |
| 20 | constexpr size_t SETS_GROW_RATE = 16; | 20 | constexpr size_t SETS_GROW_RATE = 16; |
| 21 | constexpr s32 SCORE_THRESHOLD = 3; | 21 | constexpr s32 SCORE_THRESHOLD = 3; |
| 22 | constexpr u32 SETS_PER_POOL = 64; | ||
| 23 | 22 | ||
| 24 | struct DescriptorBank { | 23 | struct DescriptorBank { |
| 25 | DescriptorBankInfo info; | 24 | DescriptorBankInfo info; |
| @@ -59,11 +58,12 @@ static DescriptorBankInfo MakeBankInfo(std::span<const Shader::Info> infos) { | |||
| 59 | static void AllocatePool(const Device& device, DescriptorBank& bank) { | 58 | static void AllocatePool(const Device& device, DescriptorBank& bank) { |
| 60 | std::array<VkDescriptorPoolSize, 6> pool_sizes; | 59 | std::array<VkDescriptorPoolSize, 6> pool_sizes; |
| 61 | size_t pool_cursor{}; | 60 | size_t pool_cursor{}; |
| 61 | const u32 sets_per_pool = device.GetSetsPerPool(); | ||
| 62 | const auto add = [&](VkDescriptorType type, u32 count) { | 62 | const auto add = [&](VkDescriptorType type, u32 count) { |
| 63 | if (count > 0) { | 63 | if (count > 0) { |
| 64 | pool_sizes[pool_cursor++] = { | 64 | pool_sizes[pool_cursor++] = { |
| 65 | .type = type, | 65 | .type = type, |
| 66 | .descriptorCount = count * SETS_PER_POOL, | 66 | .descriptorCount = count * sets_per_pool, |
| 67 | }; | 67 | }; |
| 68 | } | 68 | } |
| 69 | }; | 69 | }; |
| @@ -78,7 +78,7 @@ static void AllocatePool(const Device& device, DescriptorBank& bank) { | |||
| 78 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, | 78 | .sType = VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO, |
| 79 | .pNext = nullptr, | 79 | .pNext = nullptr, |
| 80 | .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, | 80 | .flags = VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT, |
| 81 | .maxSets = SETS_PER_POOL, | 81 | .maxSets = sets_per_pool, |
| 82 | .poolSizeCount = static_cast<u32>(pool_cursor), | 82 | .poolSizeCount = static_cast<u32>(pool_cursor), |
| 83 | .pPoolSizes = std::data(pool_sizes), | 83 | .pPoolSizes = std::data(pool_sizes), |
| 84 | })); | 84 | })); |
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) { | |||
| 765 | const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass; | 765 | const Maxwell::StencilOp zpass = regs.stencil_front_op_zpass; |
| 766 | const Maxwell::ComparisonOp compare = regs.stencil_front_func_func; | 766 | const Maxwell::ComparisonOp compare = regs.stencil_front_func_func; |
| 767 | if (regs.stencil_two_side_enable) { | 767 | if (regs.stencil_two_side_enable) { |
| 768 | scheduler.Record([fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf) { | 768 | // Separate stencil op per face |
| 769 | cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), | ||
| 770 | MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), | ||
| 771 | MaxwellToVK::ComparisonOp(compare)); | ||
| 772 | }); | ||
| 773 | } else { | ||
| 774 | const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail; | 769 | const Maxwell::StencilOp back_fail = regs.stencil_back_op_fail; |
| 775 | const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail; | 770 | const Maxwell::StencilOp back_zfail = regs.stencil_back_op_zfail; |
| 776 | const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass; | 771 | const Maxwell::StencilOp back_zpass = regs.stencil_back_op_zpass; |
| @@ -785,6 +780,13 @@ void RasterizerVulkan::UpdateStencilOp(Tegra::Engines::Maxwell3D::Regs& regs) { | |||
| 785 | MaxwellToVK::StencilOp(back_zfail), | 780 | MaxwellToVK::StencilOp(back_zfail), |
| 786 | MaxwellToVK::ComparisonOp(back_compare)); | 781 | MaxwellToVK::ComparisonOp(back_compare)); |
| 787 | }); | 782 | }); |
| 783 | } else { | ||
| 784 | // Front face defines the stencil op of both faces | ||
| 785 | scheduler.Record([fail, zfail, zpass, compare](vk::CommandBuffer cmdbuf) { | ||
| 786 | cmdbuf.SetStencilOpEXT(VK_STENCIL_FACE_FRONT_AND_BACK, MaxwellToVK::StencilOp(fail), | ||
| 787 | MaxwellToVK::StencilOp(zpass), MaxwellToVK::StencilOp(zfail), | ||
| 788 | MaxwellToVK::ComparisonOp(compare)); | ||
| 789 | }); | ||
| 788 | } | 790 | } |
| 789 | } | 791 | } |
| 790 | 792 | ||
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 | |||
| 243 | SetupFamilies(surface); | 243 | SetupFamilies(surface); |
| 244 | SetupFeatures(); | 244 | SetupFeatures(); |
| 245 | SetupProperties(); | 245 | SetupProperties(); |
| 246 | CollectTelemetryParameters(); | ||
| 246 | 247 | ||
| 247 | const auto queue_cis = GetDeviceQueueCreateInfos(); | 248 | const auto queue_cis = GetDeviceQueueCreateInfos(); |
| 248 | const std::vector extensions = LoadExtensions(surface != nullptr); | 249 | const std::vector extensions = LoadExtensions(surface != nullptr); |
| @@ -368,6 +369,18 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 368 | }; | 369 | }; |
| 369 | SetNext(next, demote); | 370 | SetNext(next, demote); |
| 370 | 371 | ||
| 372 | if (driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE) { | ||
| 373 | const u32 version = properties.driverVersion; | ||
| 374 | // Broken in this driver | ||
| 375 | if (version > VK_MAKE_API_VERSION(0, 2, 0, 193)) { | ||
| 376 | LOG_WARNING(Render_Vulkan, "AMD proprietary driver versions newer than 21.9.1 " | ||
| 377 | "(windows) / 0.2.0.194 (amdvlk) have " | ||
| 378 | "broken VkPhysicalDeviceFloat16Int8FeaturesKHR"); | ||
| 379 | is_int8_supported = false; | ||
| 380 | is_float16_supported = false; | ||
| 381 | } | ||
| 382 | } | ||
| 383 | |||
| 371 | if (is_int8_supported || is_float16_supported) { | 384 | if (is_int8_supported || is_float16_supported) { |
| 372 | VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8{ | 385 | VkPhysicalDeviceFloat16Int8FeaturesKHR float16_int8{ |
| 373 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, | 386 | .sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR, |
| @@ -560,7 +573,6 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 560 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); | 573 | logical = vk::Device::Create(physical, queue_cis, extensions, first_next, dld); |
| 561 | 574 | ||
| 562 | CollectPhysicalMemoryInfo(); | 575 | CollectPhysicalMemoryInfo(); |
| 563 | CollectTelemetryParameters(); | ||
| 564 | CollectToolingInfo(); | 576 | CollectToolingInfo(); |
| 565 | 577 | ||
| 566 | if (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { | 578 | if (driver_id == VK_DRIVER_ID_NVIDIA_PROPRIETARY_KHR) { |
| @@ -587,6 +599,26 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR | |||
| 587 | ext_extended_dynamic_state = false; | 599 | ext_extended_dynamic_state = false; |
| 588 | } | 600 | } |
| 589 | } | 601 | } |
| 602 | |||
| 603 | sets_per_pool = 64; | ||
| 604 | if (driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE) { | ||
| 605 | // AMD drivers need a higher amount of Sets per Pool in certain circunstances like in XC2. | ||
| 606 | sets_per_pool = 96; | ||
| 607 | } | ||
| 608 | |||
| 609 | const bool is_amd = driver_id == VK_DRIVER_ID_AMD_PROPRIETARY || | ||
| 610 | driver_id == VK_DRIVER_ID_MESA_RADV || | ||
| 611 | driver_id == VK_DRIVER_ID_AMD_OPEN_SOURCE; | ||
| 612 | if (ext_sampler_filter_minmax && is_amd) { | ||
| 613 | // Disable ext_sampler_filter_minmax on AMD GCN4 and lower as it is broken. | ||
| 614 | if (!is_float16_supported) { | ||
| 615 | LOG_WARNING( | ||
| 616 | Render_Vulkan, | ||
| 617 | "Blacklisting AMD GCN4 and lower for VK_EXT_SAMPLER_FILTER_MINMAX_EXTENSION_NAME"); | ||
| 618 | ext_sampler_filter_minmax = false; | ||
| 619 | } | ||
| 620 | } | ||
| 621 | |||
| 590 | if (ext_vertex_input_dynamic_state && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { | 622 | if (ext_vertex_input_dynamic_state && driver_id == VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS) { |
| 591 | LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state"); | 623 | LOG_WARNING(Render_Vulkan, "Blacklisting Intel for VK_EXT_vertex_input_dynamic_state"); |
| 592 | ext_vertex_input_dynamic_state = false; | 624 | 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: | |||
| 323 | return device_access_memory; | 323 | return device_access_memory; |
| 324 | } | 324 | } |
| 325 | 325 | ||
| 326 | u32 GetSetsPerPool() const { | ||
| 327 | return sets_per_pool; | ||
| 328 | } | ||
| 329 | |||
| 326 | private: | 330 | private: |
| 327 | /// Checks if the physical device is suitable. | 331 | /// Checks if the physical device is suitable. |
| 328 | void CheckSuitability(bool requires_swapchain) const; | 332 | void CheckSuitability(bool requires_swapchain) const; |
| @@ -376,6 +380,7 @@ private: | |||
| 376 | VkShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced. | 380 | VkShaderStageFlags guest_warp_stages{}; ///< Stages where the guest warp size can be forced. |
| 377 | u64 device_access_memory{}; ///< Total size of device local memory in bytes. | 381 | u64 device_access_memory{}; ///< Total size of device local memory in bytes. |
| 378 | u32 max_push_descriptors{}; ///< Maximum number of push descriptors | 382 | u32 max_push_descriptors{}; ///< Maximum number of push descriptors |
| 383 | u32 sets_per_pool{}; ///< Sets per Description Pool | ||
| 379 | bool is_optimal_astc_supported{}; ///< Support for native ASTC. | 384 | bool is_optimal_astc_supported{}; ///< Support for native ASTC. |
| 380 | bool is_float16_supported{}; ///< Support for float16 arithmetic. | 385 | bool is_float16_supported{}; ///< Support for float16 arithmetic. |
| 381 | bool is_int8_supported{}; ///< Support for int8 arithmetic. | 386 | bool is_int8_supported{}; ///< Support for int8 arithmetic. |