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
VkDescriptorSet previous_set = m_current_frame->descriptor_set.value();
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)
{

View file

@ -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);
}
}

View file

@ -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);
}
}

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)
{
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<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]]
{

View file

@ -4,7 +4,7 @@
#include "commands.h"
#include "device.h"
#include <vector>
#include "Emu/RSX/rsx_utils.h"
namespace vk
{
@ -24,7 +24,7 @@ namespace vk
private:
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;
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<VkCopyDescriptorSet>& 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<VkCopyDescriptorSet>& 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<VkBufferView> m_buffer_view_pool;
std::vector<VkDescriptorBufferInfo> m_buffer_info_pool;
std::vector<VkDescriptorImageInfo> m_image_info_pool;
rsx::simple_array<VkBufferView> m_buffer_view_pool;
rsx::simple_array<VkDescriptorBufferInfo> m_buffer_info_pool;
rsx::simple_array<VkDescriptorImageInfo> m_image_info_pool;
std::vector<VkWriteDescriptorSet> m_pending_writes;
std::vector<VkCopyDescriptorSet> m_pending_copies;
rsx::simple_array<VkWriteDescriptorSet> m_pending_writes;
rsx::simple_array<VkCopyDescriptorSet> m_pending_copies;
};
void flush_descriptor_updates();