From 2ae9753d7944c5f1dc721c278c13d3f92ece1a75 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 13 Jun 2025 13:15:22 +0300 Subject: [PATCH] vk: Lazy register/derigeter of hot data --- rpcs3/Emu/RSX/VK/VKCompute.cpp | 5 +++ rpcs3/Emu/RSX/VK/VKCompute.h | 5 +++ rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp | 3 +- rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp | 50 +++++++++++++----------- rpcs3/Emu/RSX/VK/vkutils/descriptors.h | 1 + 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKCompute.cpp b/rpcs3/Emu/RSX/VK/VKCompute.cpp index c164edddd7..6f676e60c9 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.cpp +++ b/rpcs3/Emu/RSX/VK/VKCompute.cpp @@ -250,6 +250,11 @@ namespace vk void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd, const u32* params, u8 count) { + if (!m_program) + { + load_program(cmd); + } + ensure(use_push_constants); vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, count * 4, params); } diff --git a/rpcs3/Emu/RSX/VK/VKCompute.h b/rpcs3/Emu/RSX/VK/VKCompute.h index fa053afe50..9ffeb1ca7f 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.h +++ b/rpcs3/Emu/RSX/VK/VKCompute.h @@ -451,6 +451,11 @@ namespace vk void set_parameters(const vk::command_buffer& cmd) { + if (!m_program) + { + load_program(cmd); + } + vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, push_constants_size, params.data); } diff --git a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp index 8ad89bc4a9..c03a9e7b00 100644 --- a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp +++ b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp @@ -402,7 +402,8 @@ namespace vk break; } - bind_sets[count++] = set.m_descriptor_set.value(); // Current set pointer for binding + bind_sets[count++] = set.m_descriptor_set.value(); // Current set pointer for binding + set.m_descriptor_set.on_bind(); // Notify async queue set.next_descriptor_set(); // Flush queue and update pointers } diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp index 5a2ad92dab..ebe94fd8d3 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp @@ -14,44 +14,37 @@ namespace vk public: inline void flush_all() { + reader_lock lock(m_notifications_lock); + for (auto& set : m_notification_list) { set->flush(); } + + m_notification_list.clear(); } void register_(descriptor_set* set) { - // Rare event, upon creation of a new set tracker. - // Check for spurious 'new' events when the aux context is taking over - for (const auto& set_ : m_notification_list) - { - if (set_ == set) return; - } + std::lock_guard lock(m_notifications_lock); m_notification_list.push_back(set); - rsx_log.warning("[descriptor_manager::register] Now monitoring %u descriptor sets", m_notification_list.size()); + // rsx_log.notice("[descriptor_manager::register] Now monitoring %u descriptor sets", m_notification_list.size()); } void deregister(descriptor_set* set) { - for (auto it = m_notification_list.begin(); it != m_notification_list.end(); ++it) - { - if (*it == set) - { - *it = m_notification_list.back(); - m_notification_list.pop_back(); - break; - } - } + std::lock_guard lock(m_notifications_lock); - rsx_log.warning("[descriptor_manager::deregister] Now monitoring %u descriptor sets", m_notification_list.size()); + m_notification_list.erase_if(FN(x == set)); + // rsx_log.notice("[descriptor_manager::deregister] Now monitoring %u descriptor sets", m_notification_list.size()); } dispatch_manager() = default; private: rsx::simple_array m_notification_list; + shared_mutex m_notifications_lock; dispatch_manager(const dispatch_manager&) = delete; dispatch_manager& operator = (const dispatch_manager&) = delete; @@ -295,11 +288,6 @@ namespace vk m_in_use = true; m_update_after_bind_mask = g_render_device->get_descriptor_update_after_bind_support(); - - if (m_update_after_bind_mask) - { - g_fxo->get().register_(this); - } } else if (m_push_type_mask & ~m_update_after_bind_mask) { @@ -450,13 +438,29 @@ namespace vk m_dynamic_offsets[offset.location] = offset.value; } - void descriptor_set::bind(const vk::command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout) + void descriptor_set::on_bind() { + if (!m_push_type_mask) + { + return; + } + + // We have queued writes if ((m_push_type_mask & ~m_update_after_bind_mask) || (m_pending_writes.size() >= max_cache_size)) { flush(); } + else if (m_update_after_bind_mask) + { + // Register for async flush + g_fxo->get().register_(this); + } + } + + void descriptor_set::bind(const vk::command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout) + { + on_bind(); vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, ::size32(m_dynamic_offsets), m_dynamic_offsets.data()); } diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h index c3e67302ae..556fe5d0b9 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h @@ -106,6 +106,7 @@ namespace vk void push(rsx::simple_array& write_cmds, u32 type_mask = umax); void push(const descriptor_set_dynamic_offset_t& offset); + void on_bind(); void bind(const vk::command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout); void flush();