vk: Rewrite descriptor write template management

This commit is contained in:
kd-11
2025-08-13 02:24:56 +03:00
committed by kd-11
parent c4426b0f07
commit 3ee626ce3c
5 changed files with 68 additions and 47 deletions
+19
View File
@@ -8,6 +8,13 @@
namespace rsx namespace rsx
{ {
template <typename C, typename T>
concept span_like =
requires(C& c) {
{ c.data() } -> std::convertible_to<const T*>;
{ c.size() } -> std::integral;
};
template <typename Ty> template <typename Ty>
requires std::is_trivially_destructible_v<Ty> requires std::is_trivially_destructible_v<Ty>
struct simple_array struct simple_array
@@ -82,6 +89,18 @@ namespace rsx
swap(other); swap(other);
} }
template <typename Container>
requires span_like<Container, Ty>
simple_array(const Container& container)
{
resize(container.size());
if (_size)
{
std::memcpy(_data, container.data(), size_bytes());
}
}
simple_array& operator=(const simple_array& other) simple_array& operator=(const simple_array& other)
{ {
if (&other != this) if (&other != this)
+30 -36
View File
@@ -38,6 +38,12 @@ namespace vk
return !!ptr && *ptr == b; return !!ptr && *ptr == b;
} }
bool operator == (const descriptor_slot_t& a, const std::span<const VkDescriptorImageInfo>& b)
{
const auto ptr = std::get_if<descriptor_image_array_t>(&a);
return !!ptr && ptr->size() == b.size() && !std::memcmp(ptr->data(), b.data(), b.size_bytes());
}
VkDescriptorType to_descriptor_type(program_input_type type) VkDescriptorType to_descriptor_type(program_input_type type)
{ {
switch (type) switch (type)
@@ -337,25 +343,14 @@ namespace vk
m_sets[set_id].notify_descriptor_slot_updated(binding_point, buffer_view); m_sets[set_id].notify_descriptor_slot_updated(binding_point, buffer_view);
} }
void program::bind_uniform_array(const VkDescriptorImageInfo* image_descriptors, int count, u32 set_id, u32 binding_point) void program::bind_uniform_array(const std::span<const VkDescriptorImageInfo>& image_descriptors, u32 set_id, u32 binding_point)
{ {
// Non-caching write if (m_sets[set_id].m_descriptor_slots[binding_point] == image_descriptors)
auto& set = m_sets[set_id];
auto& arr = set.m_scratch_images_array;
descriptor_array_ref_t data
{ {
.first = arr.size(), return;
.count = static_cast<u32>(count)
};
arr.reserve(arr.size() + static_cast<u32>(count));
for (int i = 0; i < count; ++i)
{
arr.push_back(image_descriptors[i]);
} }
set.notify_descriptor_slot_updated(binding_point, data); m_sets[set_id].notify_descriptor_slot_updated(binding_point, image_descriptors);
} }
void program::create_pipeline_layout() void program::create_pipeline_layout()
@@ -474,10 +469,16 @@ namespace vk
void descriptor_table_t::create_descriptor_template() void descriptor_table_t::create_descriptor_template()
{ {
auto push_descriptor_slot = [this](unsigned idx) auto push_descriptor_slot = [this](unsigned idx, VkWriteDescriptorSet& writer)
{ {
const auto& slot = m_descriptor_slots[idx]; const auto& slot = m_descriptor_slots[idx];
const VkDescriptorType type = m_descriptor_types[idx]; const VkDescriptorType type = m_descriptor_types[idx];
writer.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET;
writer.dstBinding = idx;
writer.descriptorCount = 1;
writer.descriptorType = type;
if (auto ptr = std::get_if<VkDescriptorImageInfo>(&slot)) if (auto ptr = std::get_if<VkDescriptorImageInfo>(&slot))
{ {
m_descriptor_set.push(*ptr, type, idx); m_descriptor_set.push(*ptr, type, idx);
@@ -496,11 +497,10 @@ namespace vk
return; return;
} }
if (auto ptr = std::get_if<descriptor_array_ref_t>(&slot)) if (auto ptr = std::get_if<descriptor_image_array_t>(&slot))
{ {
ensure(type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); // Only type supported at the moment writer.descriptorCount = ptr->size();
ensure((ptr->first + ptr->count) <= m_scratch_images_array.size()); m_descriptor_set.push(ptr->data(), ptr->size(), type, idx);
m_descriptor_set.push(m_scratch_images_array.data() + ptr->first, ptr->count, type, idx);
return; return;
} }
@@ -508,23 +508,20 @@ namespace vk
}; };
m_descriptor_template_typemask = 0u; m_descriptor_template_typemask = 0u;
m_descriptor_template.clear();
for (unsigned i = 0; i < m_descriptor_slots.size(); ++i) for (unsigned i = 0; i < m_descriptor_slots.size(); ++i)
{ {
m_descriptor_template_typemask |= (1u << static_cast<u32>(m_descriptor_types[i])); m_descriptor_template_typemask |= (1u << static_cast<u32>(m_descriptor_types[i]));
if (m_descriptors_dirty[i]) VkWriteDescriptorSet _template{};
{
// Push
push_descriptor_slot(i);
m_descriptors_dirty[i] = false;
continue;
}
push_descriptor_slot(i); push_descriptor_slot(i, _template);
m_descriptors_dirty[i] = false;
m_descriptor_template.push_back(_template);
} }
m_descriptor_template = m_descriptor_set.peek(); m_descriptor_template_cache_id = umax;
m_descriptor_template_cache_id = m_descriptor_set.cache_id(); ensure(m_descriptor_template.size() == m_descriptor_slots.size());
} }
void descriptor_table_t::update_descriptor_template() void descriptor_table_t::update_descriptor_template()
@@ -551,12 +548,10 @@ namespace vk
return; return;
} }
// FIXME: This sucks even if only used by interpreter. Do better. if (auto ptr = std::get_if<descriptor_image_array_t>(&slot))
if (auto ptr = std::get_if<descriptor_array_ref_t>(&slot))
{ {
ensure(type == VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); ensure(m_descriptor_template[idx].descriptorCount == ptr->size());
ensure((ptr->first + ptr->count) <= m_scratch_images_array.size()); m_descriptor_template[idx].pImageInfo = m_descriptor_set.store(*ptr);
m_descriptor_set.push(m_scratch_images_array.data() + ptr->first, ptr->count, type, idx);
return; return;
} }
@@ -611,7 +606,6 @@ namespace vk
m_descriptor_set.on_bind(); m_descriptor_set.on_bind();
m_any_descriptors_dirty = false; m_any_descriptors_dirty = false;
m_scratch_images_array.clear();
return m_descriptor_set.value(); return m_descriptor_set.value();
} }
+3 -10
View File
@@ -113,13 +113,8 @@ namespace vk
VkShaderModule get_handle() const; VkShaderModule get_handle() const;
}; };
struct descriptor_array_ref_t using descriptor_image_array_t = rsx::simple_array<VkDescriptorImageInfo>;
{ using descriptor_slot_t = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView, descriptor_image_array_t>;
u32 first = 0;
u32 count = 0;
};
using descriptor_slot_t = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView, descriptor_array_ref_t>;
struct descriptor_table_t struct descriptor_table_t
{ {
@@ -140,8 +135,6 @@ namespace vk
std::vector<bool> m_descriptors_dirty; std::vector<bool> m_descriptors_dirty;
bool m_any_descriptors_dirty = false; bool m_any_descriptors_dirty = false;
rsx::simple_array< VkDescriptorImageInfo> m_scratch_images_array;
void init(VkDevice dev); void init(VkDevice dev);
void destroy(); void destroy();
@@ -212,7 +205,7 @@ namespace vk
void bind_uniform(const VkBufferView &buffer_view, u32 set_id, u32 binding_point); void bind_uniform(const VkBufferView &buffer_view, u32 set_id, u32 binding_point);
void bind_uniform(const VkBufferView &buffer_view, ::glsl::program_domain domain, program_input_type type, const std::string &binding_name); void bind_uniform(const VkBufferView &buffer_view, ::glsl::program_domain domain, program_input_type type, const std::string &binding_name);
void bind_uniform_array(const VkDescriptorImageInfo* image_descriptors, int count, u32 set_id, u32 binding_point); void bind_uniform_array(const std::span<const VkDescriptorImageInfo>& image_descriptors,u32 set_id, u32 binding_point);
inline VkPipelineLayout layout() const { return m_pipeline_layout; } inline VkPipelineLayout layout() const { return m_pipeline_layout; }
inline VkPipeline value() const { return m_pipeline; } inline VkPipeline value() const { return m_pipeline; }
+1 -1
View File
@@ -432,7 +432,7 @@ namespace vk
const VkDescriptorImageInfo* texture_ptr = sampled_images.data(); const VkDescriptorImageInfo* texture_ptr = sampled_images.data();
for (u32 i = 0; i < 4; ++i, ++binding, texture_ptr += 16) for (u32 i = 0; i < 4; ++i, ++binding, texture_ptr += 16)
{ {
m_current_interpreter->bind_uniform_array(texture_ptr, 16, set, binding); m_current_interpreter->bind_uniform_array({ texture_ptr, 16 }, set, binding);
} }
} }
+15
View File
@@ -164,6 +164,21 @@ namespace vk
return &m_image_info_pool.back(); return &m_image_info_pool.back();
} }
FORCE_INLINE VkDescriptorImageInfo* store(const rsx::simple_array<VkDescriptorImageInfo>& image_infos)
{
const auto offset = m_image_info_pool.size();
m_image_info_pool += image_infos;
return &m_image_info_pool[offset];
}
FORCE_INLINE bool storage_cache_pressure() const
{
return
m_image_info_pool.size() >= max_cache_size ||
m_buffer_info_pool.size() >= max_cache_size ||
m_buffer_view_pool.size() >= max_cache_size;
}
// Temporary storage accessors // Temporary storage accessors
const rsx::simple_array<WriteDescriptorSetT> peek() const { return m_pending_writes; } const rsx::simple_array<WriteDescriptorSetT> peek() const { return m_pending_writes; }
u64 cache_id() const { return m_storage_cache_id; } u64 cache_id() const { return m_storage_cache_id; }