From f241825c730b0284159a06db58dd56dd6e4530d0 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 15 Jun 2025 14:21:25 +0300 Subject: [PATCH] vk: Update binding model for compute jobs --- rpcs3/Emu/RSX/Common/simple_array.hpp | 5 +++ rpcs3/Emu/RSX/VK/VKCompute.cpp | 23 +++++++------- rpcs3/Emu/RSX/VK/VKCompute.h | 33 ++++++++++---------- rpcs3/Emu/RSX/VK/VKResolveHelper.h | 2 +- rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp | 2 +- rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h | 2 +- rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp | 22 +++++++------ 7 files changed, 47 insertions(+), 42 deletions(-) diff --git a/rpcs3/Emu/RSX/Common/simple_array.hpp b/rpcs3/Emu/RSX/Common/simple_array.hpp index dfec324eeb..06e0b1870d 100644 --- a/rpcs3/Emu/RSX/Common/simple_array.hpp +++ b/rpcs3/Emu/RSX/Common/simple_array.hpp @@ -305,6 +305,11 @@ namespace rsx return _size * sizeof(Ty); } + u32 size_bytes32() const + { + return _size * sizeof(Ty); + } + u32 capacity() const { return _capacity; diff --git a/rpcs3/Emu/RSX/VK/VKCompute.cpp b/rpcs3/Emu/RSX/VK/VKCompute.cpp index 6f676e60c9..9d91773988 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.cpp +++ b/rpcs3/Emu/RSX/VK/VKCompute.cpp @@ -132,7 +132,7 @@ namespace vk m_program = compiler->compile(create_info, vk::pipe_compiler::COMPILE_INLINE, {}, get_inputs()); } - bind_resources(); + bind_resources(cmd); m_program->bind(cmd, VK_PIPELINE_BIND_POINT_COMPUTE); } @@ -243,20 +243,19 @@ namespace vk m_src += suffix; } - void cs_shuffle_base::bind_resources() + void cs_shuffle_base::bind_resources(const vk::command_buffer& cmd) { + set_parameters(cmd); m_program->bind_uniform({ m_data->value, m_data_offset, m_data_length }, 0, 0); } - void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd, const u32* params, u8 count) + void cs_shuffle_base::set_parameters(const vk::command_buffer& cmd) { - if (!m_program) + if (!m_params.empty()) { - load_program(cmd); + ensure(use_push_constants); + vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, m_params.size_bytes32(), m_params.data()); } - - ensure(use_push_constants); - vkCmdPushConstants(cmd, m_program->layout(), VK_SHADER_STAGE_COMPUTE_BIT, 0, count * 4, params); } void cs_shuffle_base::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_length, u32 data_offset) @@ -294,15 +293,15 @@ namespace vk " uint stencil_offset;\n"; } - void cs_interleave_task::bind_resources() + void cs_interleave_task::bind_resources(const vk::command_buffer& cmd) { + set_parameters(cmd); m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0); } void cs_interleave_task::run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset) { - u32 parameters[4] = { data_length, zeta_offset - data_offset, stencil_offset - data_offset, 0 }; - set_parameters(cmd, parameters, 4); + m_params = { data_length, zeta_offset - data_offset, stencil_offset - data_offset, 0 }; ensure(stencil_offset > data_offset); m_ssbo_length = stencil_offset + (data_length / 4) - data_offset; @@ -354,7 +353,7 @@ namespace vk m_src = fmt::replace_all(m_src, syntax_replace); } - void cs_aggregator::bind_resources() + void cs_aggregator::bind_resources(const vk::command_buffer& cmd) { m_program->bind_uniform({ src->value, 0, block_length }, 0, 0); m_program->bind_uniform({ dst->value, 0, 4 }, 0, 1); diff --git a/rpcs3/Emu/RSX/VK/VKCompute.h b/rpcs3/Emu/RSX/VK/VKCompute.h index 9ffeb1ca7f..0dfa80f4f5 100644 --- a/rpcs3/Emu/RSX/VK/VKCompute.h +++ b/rpcs3/Emu/RSX/VK/VKCompute.h @@ -35,7 +35,7 @@ namespace vk void destroy(); virtual std::vector get_inputs(); - virtual void bind_resources() {} + virtual void bind_resources(const vk::command_buffer& cmd) {} void load_program(const vk::command_buffer& cmd); @@ -50,6 +50,8 @@ namespace vk u32 m_data_length = 0; u32 kernel_size = 1; + rsx::simple_array m_params; + std::string variables, work_kernel, loop_advance, suffix; std::string method_declarations; @@ -57,9 +59,9 @@ namespace vk void build(const char* function_name, u32 _kernel_size = 0); - void bind_resources() override; + void bind_resources(const vk::command_buffer& cmd) override; - void set_parameters(const vk::command_buffer& cmd, const u32* params, u8 count); + void set_parameters(const vk::command_buffer& cmd); void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_length, u32 data_offset = 0); }; @@ -125,7 +127,7 @@ namespace vk cs_interleave_task(); - void bind_resources() override; + void bind_resources(const vk::command_buffer& cmd) override; void run(const vk::command_buffer& cmd, const vk::buffer* data, u32 data_offset, u32 data_length, u32 zeta_offset, u32 stencil_offset); }; @@ -342,8 +344,9 @@ namespace vk cs_shuffle_base::build(""); } - void bind_resources() override + void bind_resources(const vk::command_buffer& cmd) override { + set_parameters(cmd); m_program->bind_uniform({ m_data->value, m_data_offset, m_ssbo_length }, 0, 0); } @@ -361,8 +364,7 @@ namespace vk data_offset = src_offset; } - u32 parameters[4] = { src_length, src_offset - data_offset, dst_offset - data_offset, 0 }; - set_parameters(cmd, parameters, 4); + m_params = { src_length, src_offset - data_offset, dst_offset - data_offset, 0 }; cs_shuffle_base::run(cmd, data, src_length, data_offset); } }; @@ -443,19 +445,16 @@ namespace vk m_src = fmt::replace_all(m_src, syntax_replace); } - void bind_resources() override + void bind_resources(const vk::command_buffer& cmd) override { + set_parameters(cmd); + m_program->bind_uniform({ src_buffer->value, in_offset, block_length }, 0, 0); m_program->bind_uniform({ dst_buffer->value, out_offset, block_length }, 0, 1); } 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); } @@ -475,7 +474,6 @@ namespace vk params.logw = rsx::ceil_log2(width); params.logh = rsx::ceil_log2(height); params.logd = rsx::ceil_log2(depth); - set_parameters(cmd); const u32 num_bytes_per_invocation = (sizeof(_BlockType) * optimal_group_size); const u32 linear_invocations = utils::aligned_div(data_length, num_bytes_per_invocation); @@ -492,7 +490,7 @@ namespace vk cs_aggregator(); - void bind_resources() override; + void bind_resources(const vk::command_buffer& cmd) override; void run(const vk::command_buffer& cmd, const vk::buffer* dst, const vk::buffer* src, u32 num_words); }; @@ -576,8 +574,10 @@ namespace vk m_src = fmt::replace_all(m_src, syntax_replace); } - void bind_resources() override + void bind_resources(const vk::command_buffer& cmd) override { + set_parameters(cmd); + const auto op = static_cast(Op); m_program->bind_uniform({ src_buffer->value, in_offset, in_block_length }, 0u, 0u ^ op); m_program->bind_uniform({ dst_buffer->value, out_offset, out_block_length }, 0u, 1u ^ op); @@ -648,7 +648,6 @@ namespace vk params.image_height = (Op == RSX_detiler_op::decode) ? tile_aligned_height : config.image_height; params.image_pitch = config.image_pitch; params.image_bpp = config.image_bpp; - set_parameters(cmd); const u32 subtexels_per_invocation = (config.image_bpp < 4) ? (4 / config.image_bpp) : 1; const u32 virtual_width = config.image_width / subtexels_per_invocation; diff --git a/rpcs3/Emu/RSX/VK/VKResolveHelper.h b/rpcs3/Emu/RSX/VK/VKResolveHelper.h index 9bc9e4f532..a9064eff95 100644 --- a/rpcs3/Emu/RSX/VK/VKResolveHelper.h +++ b/rpcs3/Emu/RSX/VK/VKResolveHelper.h @@ -49,7 +49,7 @@ namespace vk return result; } - void bind_resources() override + void bind_resources(const vk::command_buffer& cmd) override { auto msaa_view = multisampled->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_VIEW_MULTISAMPLED)); auto resolved_view = resolve->get_view(rsx::default_remap_vector.with_encoding(VK_REMAP_IDENTITY)); diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp index 589defd3e8..23a4733c60 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr1/fsr_pass.cpp @@ -97,7 +97,7 @@ namespace vk return result; } - void fsr_pass::bind_resources() + void fsr_pass::bind_resources(const vk::command_buffer& cmd) { // Bind relevant stuff if (!m_sampler) diff --git a/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h b/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h index 6d9b15d72a..7bff58b049 100644 --- a/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h +++ b/rpcs3/Emu/RSX/VK/upscalers/fsr_pass.h @@ -20,7 +20,7 @@ namespace vk u32 m_constants_buf[20]; std::vector get_inputs() override; - void bind_resources() override; + void bind_resources(const vk::command_buffer&) override; virtual void configure(const vk::command_buffer& cmd) = 0; diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp index d8e8fcd7ff..a49dc66301 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp @@ -14,7 +14,7 @@ namespace vk public: inline void flush_all() { - std::shared_lock lock(m_notifications_lock); + std::lock_guard lock(m_notifications_lock); for (auto& set : m_notification_list) { @@ -44,7 +44,7 @@ namespace vk private: rsx::simple_array m_notification_list; - std::shared_mutex m_notifications_lock; + std::mutex m_notifications_lock; dispatch_manager(const dispatch_manager&) = delete; dispatch_manager& operator = (const dispatch_manager&) = delete; @@ -81,17 +81,17 @@ namespace vk } else { - binding_flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT_EXT; + binding_flags[i] = VK_DESCRIPTOR_BINDING_UPDATE_AFTER_BIND_BIT; } } - binding_infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO_EXT; + binding_infos.sType = VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_BINDING_FLAGS_CREATE_INFO; binding_infos.pNext = nullptr; binding_infos.bindingCount = ::size32(binding_flags); binding_infos.pBindingFlags = binding_flags.data(); infos.pNext = &binding_infos; - infos.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT_EXT; + infos.flags |= VK_DESCRIPTOR_SET_LAYOUT_CREATE_UPDATE_AFTER_BIND_POOL_BIT; VkDescriptorSetLayout result; CHECK_RESULT(vkCreateDescriptorSetLayout(*g_render_device, &infos, nullptr, &result)); @@ -442,6 +442,7 @@ namespace vk { if (!m_push_type_mask) { + ensure(m_pending_writes.empty()); return; } @@ -450,16 +451,17 @@ namespace vk (m_pending_writes.size() >= max_cache_size)) { flush(); + return; } - else if (m_update_after_bind_mask) - { - // Register for async flush - g_fxo->get().register_(this); - } + + // Register for async flush + ensure(m_update_after_bind_mask); + g_fxo->get().register_(this); } void descriptor_set::bind(const vk::command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout) { + // Notify on_bind(); vkCmdBindDescriptorSets(cmd, bind_point, layout, 0, 1, &m_handle, ::size32(m_dynamic_offsets), m_dynamic_offsets.data());