Optimize basic descriptor batching

This commit is contained in:
kd-11 2021-09-24 21:23:50 +03:00 committed by kd-11
parent 4752c4014b
commit 381c7544fa
5 changed files with 85 additions and 130 deletions

View file

@ -793,7 +793,7 @@ void VKGSRender::emit_geometry(u32 sub_index)
// Need to update descriptors; make a copy for the next draw // Need to update descriptors; make a copy for the next draw
VkDescriptorSet previous_set = m_current_frame->descriptor_set.value(); VkDescriptorSet previous_set = m_current_frame->descriptor_set.value();
m_current_frame->descriptor_set = allocate_descriptor_set(); m_current_frame->descriptor_set = allocate_descriptor_set();
std::vector<VkCopyDescriptorSet> copy_cmds(binding_table.total_descriptor_bindings); rsx::simple_array<VkCopyDescriptorSet> copy_cmds(binding_table.total_descriptor_bindings);
for (u32 n = 0; n < binding_table.total_descriptor_bindings; ++n) for (u32 n = 0; n < binding_table.total_descriptor_bindings; ++n)
{ {

View file

@ -165,21 +165,7 @@ namespace vk
{ {
if (uniform.name == uniform_name) if (uniform.name == uniform_name)
{ {
const VkWriteDescriptorSet descriptor_writer = set.push(image_descriptor, type, uniform.location);
{
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);
attribute_location_mask |= (1ull << uniform.location); attribute_location_mask |= (1ull << uniform.location);
return; return;
} }
@ -204,21 +190,7 @@ namespace vk
if (binding != ~0u) if (binding != ~0u)
{ {
const VkWriteDescriptorSet descriptor_writer = set.push(image_descriptor, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, binding);
{
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);
attribute_location_mask |= (1ull << binding); attribute_location_mask |= (1ull << binding);
return; return;
} }
@ -233,21 +205,7 @@ namespace vk
void program::bind_uniform(const VkBufferView &buffer_view, u32 binding_point, vk::descriptor_set &set) void program::bind_uniform(const VkBufferView &buffer_view, u32 binding_point, vk::descriptor_set &set)
{ {
const VkWriteDescriptorSet descriptor_writer = set.push(buffer_view, VK_DESCRIPTOR_TYPE_UNIFORM_TEXEL_BUFFER, binding_point);
{
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);
attribute_location_mask |= (1ull << 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) void program::bind_buffer(const VkDescriptorBufferInfo &buffer_descriptor, u32 binding_point, VkDescriptorType type, vk::descriptor_set &set)
{ {
const VkWriteDescriptorSet descriptor_writer = set.push(buffer_descriptor, type, binding_point);
{
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);
attribute_location_mask |= (1ull << binding_point); attribute_location_mask |= (1ull << binding_point);
} }
} }

View file

@ -513,21 +513,7 @@ namespace vk
const VkDescriptorImageInfo* texture_ptr = sampled_images.data(); const VkDescriptorImageInfo* texture_ptr = sampled_images.data();
for (u32 i = 0, binding = m_fragment_textures_start; i < 4; ++i, ++binding, texture_ptr += 16) for (u32 i = 0, binding = m_fragment_textures_start; i < 4; ++i, ++binding, texture_ptr += 16)
{ {
const VkWriteDescriptorSet descriptor_writer = set.push(texture_ptr, 16, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, binding);
{
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);
} }
} }

View file

@ -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) void descriptor_set::swap(descriptor_set& other)
{ {
other.flush(); other.flush();
@ -127,29 +103,79 @@ namespace vk
return m_handle; 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) m_buffer_view_pool.push_back(buffer_view);
{
flush();
}
m_pending_writes.push_back( m_pending_writes.push_back(
{ {
.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET, // sType
.pNext = nullptr, nullptr, // pNext
.dstSet = m_handle, m_handle, // dstSet
.dstBinding = write_cmd.dstBinding, binding, // dstBinding
.dstArrayElement = write_cmd.dstArrayElement, 0, // dstArrayElement
.descriptorCount = write_cmd.descriptorCount, 1, // descriptorCount
.descriptorType = write_cmd.descriptorType, type, // descriptorType
.pImageInfo = dup(write_cmd.pImageInfo), nullptr, // pImageInfo
.pBufferInfo = dup(write_cmd.pBufferInfo), nullptr, // pBufferInfo
.pTexelBufferView = dup(write_cmd.pTexelBufferView) &m_buffer_view_pool.back() // pTexelBufferView
}); });
} }
void descriptor_set::push(std::vector<VkCopyDescriptorSet>& 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<VkCopyDescriptorSet>& copy_cmd)
{ {
if (m_pending_copies.empty()) [[likely]] if (m_pending_copies.empty()) [[likely]]
{ {

View file

@ -4,7 +4,7 @@
#include "commands.h" #include "commands.h"
#include "device.h" #include "device.h"
#include <vector> #include "Emu/RSX/rsx_utils.h"
namespace vk namespace vk
{ {
@ -24,7 +24,7 @@ namespace vk
private: private:
const vk::render_device* m_owner = nullptr; const vk::render_device* m_owner = nullptr;
std::vector<VkDescriptorPool> m_device_pools; rsx::simple_array<VkDescriptorPool> m_device_pools;
VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE; VkDescriptorPool m_current_pool_handle = VK_NULL_HANDLE;
u32 m_current_pool_index = 0; u32 m_current_pool_index = 0;
}; };
@ -33,10 +33,6 @@ namespace vk
{ {
const size_t max_cache_size = 16384; 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 flush();
void init(); void init();
@ -52,8 +48,11 @@ namespace vk
VkDescriptorSet* ptr(); VkDescriptorSet* ptr();
VkDescriptorSet value() const; VkDescriptorSet value() const;
void push(const VkWriteDescriptorSet& write_cmd); void push(const VkBufferView& buffer_view, VkDescriptorType type, u32 binding);
void push(std::vector<VkCopyDescriptorSet>& copy_cmd); 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<VkCopyDescriptorSet>& copy_cmd);
void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout); void bind(VkCommandBuffer cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout); void bind(const command_buffer& cmd, VkPipelineBindPoint bind_point, VkPipelineLayout layout);
@ -61,12 +60,12 @@ namespace vk
private: private:
VkDescriptorSet m_handle = VK_NULL_HANDLE; VkDescriptorSet m_handle = VK_NULL_HANDLE;
std::vector<VkBufferView> m_buffer_view_pool; rsx::simple_array<VkBufferView> m_buffer_view_pool;
std::vector<VkDescriptorBufferInfo> m_buffer_info_pool; rsx::simple_array<VkDescriptorBufferInfo> m_buffer_info_pool;
std::vector<VkDescriptorImageInfo> m_image_info_pool; rsx::simple_array<VkDescriptorImageInfo> m_image_info_pool;
std::vector<VkWriteDescriptorSet> m_pending_writes; rsx::simple_array<VkWriteDescriptorSet> m_pending_writes;
std::vector<VkCopyDescriptorSet> m_pending_copies; rsx::simple_array<VkCopyDescriptorSet> m_pending_copies;
}; };
void flush_descriptor_updates(); void flush_descriptor_updates();