From 381c7544fa6daf4f0ac35d6c5dcf6174af6ca8b9 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Fri, 24 Sep 2021 21:23:50 +0300 Subject: [PATCH] Optimize basic descriptor batching --- rpcs3/Emu/RSX/VK/VKDraw.cpp | 2 +- rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp | 64 +------------- rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp | 16 +--- rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp | 108 ++++++++++++++--------- rpcs3/Emu/RSX/VK/vkutils/descriptors.h | 25 +++--- 5 files changed, 85 insertions(+), 130 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 19e9f5538a..1feaaab73a 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -793,7 +793,7 @@ void VKGSRender::emit_geometry(u32 sub_index) // Need to update descriptors; make a copy for the next draw VkDescriptorSet previous_set = m_current_frame->descriptor_set.value(); m_current_frame->descriptor_set = allocate_descriptor_set(); - std::vector copy_cmds(binding_table.total_descriptor_bindings); + rsx::simple_array copy_cmds(binding_table.total_descriptor_bindings); for (u32 n = 0; n < binding_table.total_descriptor_bindings; ++n) { diff --git a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp index 886c28015a..9fca1c58b5 100644 --- a/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp +++ b/rpcs3/Emu/RSX/VK/VKProgramPipeline.cpp @@ -165,21 +165,7 @@ namespace vk { if (uniform.name == uniform_name) { - const VkWriteDescriptorSet descriptor_writer = - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType - nullptr, // pNext - VK_NULL_HANDLE, // dstSet - uniform.location, // dstBinding - 0, // dstArrayElement - 1, // descriptorCount - type, // descriptorType - &image_descriptor, // pImageInfo - nullptr, // pBufferInfo - nullptr // pTexelBufferView - }; - - set.push(descriptor_writer); + set.push(image_descriptor, type, uniform.location); attribute_location_mask |= (1ull << uniform.location); return; } @@ -204,21 +190,7 @@ namespace vk if (binding != ~0u) { - const VkWriteDescriptorSet descriptor_writer = - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType - nullptr, // pNext - VK_NULL_HANDLE, // dstSet - binding, // dstBinding - 0, // dstArrayElement - 1, // descriptorCount - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType - &image_descriptor, // pImageInfo - nullptr, // pBufferInfo - nullptr // pTexelBufferView - }; - - set.push(descriptor_writer); + set.push(image_descriptor, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, binding); attribute_location_mask |= (1ull << binding); return; } @@ -233,21 +205,7 @@ namespace vk void program::bind_uniform(const VkBufferView &buffer_view, u32 binding_point, vk::descriptor_set &set) { - const VkWriteDescriptorSet descriptor_writer = - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType - nullptr, // pNext - VK_NULL_HANDLE, // dstSet - binding_point, // dstBinding - 0, // dstArrayElement - 1, // descriptorCount - VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER,// descriptorType - nullptr, // pImageInfo - nullptr, // pBufferInfo - &buffer_view // pTexelBufferView - }; - - set.push(descriptor_writer); + set.push(buffer_view, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, binding_point); attribute_location_mask |= (1ull << binding_point); } @@ -267,21 +225,7 @@ namespace vk void program::bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, vk::descriptor_set &set) { - const VkWriteDescriptorSet descriptor_writer = - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType - nullptr, // pNext - VK_NULL_HANDLE, // dstSet - binding_point, // dstBinding - 0, // dstArrayElement - 1, // descriptorCount - type, // descriptorType - nullptr, // pImageInfo - &buffer_descriptor, // pBufferInfo - nullptr // pTexelBufferView - }; - - set.push(descriptor_writer); + set.push(buffer_descriptor, type, binding_point); attribute_location_mask |= (1ull << binding_point); } } diff --git a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp index a6a33c1ed9..3396b83445 100644 --- a/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp +++ b/rpcs3/Emu/RSX/VK/VKShaderInterpreter.cpp @@ -513,21 +513,7 @@ namespace vk const VkDescriptorImageInfo* texture_ptr = sampled_images.data(); for (u32 i = 0, binding = m_fragment_textures_start; i < 4; ++i, ++binding, texture_ptr += 16) { - const VkWriteDescriptorSet descriptor_writer = - { - VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType - nullptr, // pNext - VK_NULL_HANDLE, // dstSet - binding, // dstBinding - 0, // dstArrayElement - 16, // descriptorCount - VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, // descriptorType - texture_ptr, // pImageInfo - nullptr, // pBufferInfo - nullptr // pTexelBufferView - }; - - set.push(descriptor_writer); + set.push(texture_ptr, 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, binding); } } diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp index bf5c26bd09..c30ff5e00f 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.cpp @@ -76,30 +76,6 @@ namespace vk } } - VkBufferView* descriptor_set::dup(const VkBufferView* in) - { - if (!in) return nullptr; - - m_buffer_view_pool.push_back(*in); - return &m_buffer_view_pool.back(); - } - - VkDescriptorBufferInfo* descriptor_set::dup(const VkDescriptorBufferInfo* in) - { - if (!in) return nullptr; - - m_buffer_info_pool.push_back(*in); - return &m_buffer_info_pool.back(); - } - - VkDescriptorImageInfo* descriptor_set::dup(const VkDescriptorImageInfo* in) - { - if (!in) return nullptr; - - m_image_info_pool.push_back(*in); - return &m_image_info_pool.back(); - } - void descriptor_set::swap(descriptor_set& other) { other.flush(); @@ -127,29 +103,79 @@ namespace vk return m_handle; } - void descriptor_set::push(const VkWriteDescriptorSet& write_cmd) + void descriptor_set::push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding) { - if (m_pending_writes.size() >= max_cache_size) - { - flush(); - } - + m_buffer_view_pool.push_back(buffer_view); m_pending_writes.push_back( { - .sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, - .pNext = nullptr, - .dstSet = m_handle, - .dstBinding = write_cmd.dstBinding, - .dstArrayElement = write_cmd.dstArrayElement, - .descriptorCount = write_cmd.descriptorCount, - .descriptorType = write_cmd.descriptorType, - .pImageInfo = dup(write_cmd.pImageInfo), - .pBufferInfo = dup(write_cmd.pBufferInfo), - .pTexelBufferView = dup(write_cmd.pTexelBufferView) + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType + nullptr, // pNext + m_handle, // dstSet + binding, // dstBinding + 0, // dstArrayElement + 1, // descriptorCount + type, // descriptorType + nullptr, // pImageInfo + nullptr, // pBufferInfo + &m_buffer_view_pool.back() // pTexelBufferView }); } - void descriptor_set::push(std::vector& copy_cmd) + void descriptor_set::push(const VkDescriptorBufferInfo& buffer_info, VkDescriptorType type, u32 binding) + { + m_buffer_info_pool.push_back(buffer_info); + m_pending_writes.push_back( + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType + nullptr, // pNext + m_handle, // dstSet + binding, // dstBinding + 0, // dstArrayElement + 1, // descriptorCount + type, // descriptorType + nullptr, // pImageInfo + &m_buffer_info_pool.back(), // pBufferInfo + nullptr // pTexelBufferView + }); + } + + void descriptor_set::push(const VkDescriptorImageInfo& image_info, VkDescriptorType type, u32 binding) + { + m_image_info_pool.push_back(image_info); + m_pending_writes.push_back( + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType + nullptr, // pNext + m_handle, // dstSet + binding, // dstBinding + 0, // dstArrayElement + 1, // descriptorCount + type, // descriptorType + &m_image_info_pool.back(), // pImageInfo + nullptr, // pBufferInfo + nullptr // pTexelBufferView + }); + } + + void descriptor_set::push(const VkDescriptorImageInfo* image_info, u32 count, VkDescriptorType type, u32 binding) + { + VkWriteDescriptorSet writer = + { + VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType + nullptr, // pNext + m_handle, // dstSet + binding, // dstBinding + 0, // dstArrayElement + count, // descriptorCount + type, // descriptorType + image_info, // pImageInfo + nullptr, // pBufferInfo + nullptr // pTexelBufferView + }; + vkUpdateDescriptorSets(*g_render_device, 1, &writer, 0, nullptr); + } + + void descriptor_set::push(rsx::simple_array& copy_cmd) { if (m_pending_copies.empty()) [[likely]] { diff --git a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h index 4f067cafe6..bf9f9db5ca 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/descriptors.h +++ b/rpcs3/Emu/RSX/VK/vkutils/descriptors.h @@ -4,7 +4,7 @@ #include "commands.h" #include "device.h" -#include +#include "Emu/RSX/rsx_utils.h" namespace vk { @@ -24,7 +24,7 @@ namespace vk private: const vk::render_device* m_owner = nullptr; - std::vector m_device_pools; + rsx::simple_array m_device_pools; VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE; u32 m_current_pool_index = 0; }; @@ -33,10 +33,6 @@ namespace vk { const size_t max_cache_size = 16384; - VkBufferView* dup(const VkBufferView* in); - VkDescriptorBufferInfo* dup(const VkDescriptorBufferInfo* in); - VkDescriptorImageInfo* dup(const VkDescriptorImageInfo* in); - void flush(); void init(); @@ -52,8 +48,11 @@ namespace vk VkDescriptorSet* ptr(); VkDescriptorSet value() const; - void push(const VkWriteDescriptorSet& write_cmd); - void push(std::vector& copy_cmd); + void push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding); + void push(const VkDescriptorBufferInfo& buffer_info, VkDescriptorType type, u32 binding); + void push(const VkDescriptorImageInfo& image_info, VkDescriptorType type, u32 binding); + void push(const VkDescriptorImageInfo* image_info, u32 count, VkDescriptorType type, u32 binding); + void push(rsx::simple_array& copy_cmd); void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout); void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout); @@ -61,12 +60,12 @@ namespace vk private: VkDescriptorSet m_handle = VK_NULL_HANDLE; - std::vector m_buffer_view_pool; - std::vector m_buffer_info_pool; - std::vector m_image_info_pool; + rsx::simple_array m_buffer_view_pool; + rsx::simple_array m_buffer_info_pool; + rsx::simple_array m_image_info_pool; - std::vector m_pending_writes; - std::vector m_pending_copies; + rsx::simple_array m_pending_writes; + rsx::simple_array m_pending_copies; }; void flush_descriptor_updates();