From 87677cfc852fdcabc47887dedcbca4f7dcb41227 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Wed, 13 Aug 2025 03:06:13 +0300 Subject: [PATCH] vk: Guard against concurrent access of storage pool under high pressure and MTRSX. --- rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp | 24 ++++++++++++++---------- rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp | 6 +++++- rpcs3/Emu/RSX/VK/vkutils/descriptors.h | 8 +++++++- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp index 122fd5f46d..446d4f0063 100644 --- a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp +++ b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp @@ -558,18 +558,22 @@ namespace vk fmt::throw_exception("Unexpected descriptor structure at index %u", idx); }; - const bool cache_is_valid = m_descriptor_template_cache_id == m_descriptor_set.cache_id(); - for (unsigned i = 0; i < m_descriptor_slots.size(); ++i) { - m_descriptor_template[i].dstSet = m_descriptor_set.value(); - if (!m_descriptors_dirty[i] && cache_is_valid) - { - continue; - } + std::lock_guard lock(m_descriptor_set); + const bool cache_is_valid = m_descriptor_template_cache_id == m_descriptor_set.cache_id(); - // Update - update_descriptor_slot(i); - m_descriptors_dirty[i] = false; + for (unsigned i = 0; i < m_descriptor_slots.size(); ++i) + { + m_descriptor_template[i].dstSet = m_descriptor_set.value(); + if (!m_descriptors_dirty[i] && cache_is_valid) + { + continue; + } + + // Update + update_descriptor_slot(i); + m_descriptors_dirty[i] = false; + } } // Push diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp index fc2b559226..4152e4b83a 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp @@ -437,7 +437,8 @@ namespace vk // We have queued writes if ((m_push_type_mask & ~m_update_after_bind_mask) || - (m_pending_writes.size() >= max_cache_size)) + (m_pending_writes.size() >= max_cache_size) || + storage_cache_pressure()) { flush(); return; @@ -464,11 +465,14 @@ namespace vk return; } + std::lock_guard lock(m_storage_lock); + const auto num_writes = ::size32(m_pending_writes); const auto num_copies = ::size32(m_pending_copies); vkUpdateDescriptorSets(*g_render_device, num_writes, m_pending_writes.data(), num_copies, m_pending_copies.data()); m_storage_cache_id++; + m_push_type_mask = 0; m_pending_writes.clear(); m_pending_copies.clear(); diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h index 6abb4cfc69..93ac8345e0 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h @@ -183,13 +183,19 @@ namespace vk const rsx::simple_array peek() const { return m_pending_writes; } u64 cache_id() const { return m_storage_cache_id; } + // Basic lockable for storage coherence + void lock() { m_storage_lock.lock(); } + void unlock() { m_storage_lock.unlock(); } + private: VkDescriptorSet m_handle = VK_NULL_HANDLE; u64 m_update_after_bind_mask = 0; u64 m_push_type_mask = 0; - u64 m_storage_cache_id = 0; bool m_in_use = false; + shared_mutex m_storage_lock; + atomic_t m_storage_cache_id = 0; + rsx::simple_array m_buffer_view_pool; rsx::simple_array m_buffer_info_pool; rsx::simple_array m_image_info_pool;