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

View file

@ -8,6 +8,13 @@
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>
requires std::is_trivially_destructible_v<Ty>
struct simple_array
@ -82,6 +89,18 @@ namespace rsx
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)
{
if (&other != this)

View file

@ -38,6 +38,12 @@ namespace vk
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)
{
switch (type)
@ -337,25 +343,14 @@ namespace vk
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
auto& set = m_sets[set_id];
auto& arr = set.m_scratch_images_array;
descriptor_array_ref_t data
if (m_sets[set_id].m_descriptor_slots[binding_point] == image_descriptors)
{
.first = arr.size(),
.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]);
return;
}
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()
@ -474,10 +469,16 @@ namespace vk
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 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))
{
m_descriptor_set.push(*ptr, type, idx);
@ -496,11 +497,10 @@ namespace vk
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
ensure((ptr->first + ptr->count) <= m_scratch_images_array.size());
m_descriptor_set.push(m_scratch_images_array.data() + ptr->first, ptr->count, type, idx);
writer.descriptorCount = ptr->size();
m_descriptor_set.push(ptr->data(), ptr->size(), type, idx);
return;
}
@ -508,23 +508,20 @@ namespace vk
};
m_descriptor_template_typemask = 0u;
m_descriptor_template.clear();
for (unsigned i = 0; i < m_descriptor_slots.size(); ++i)
{
m_descriptor_template_typemask |= (1u << static_cast<u32>(m_descriptor_types[i]));
if (m_descriptors_dirty[i])
{
// Push
push_descriptor_slot(i);
m_descriptors_dirty[i] = false;
continue;
}
VkWriteDescriptorSet _template{};
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 = m_descriptor_set.cache_id();
m_descriptor_template_cache_id = umax;
ensure(m_descriptor_template.size() == m_descriptor_slots.size());
}
void descriptor_table_t::update_descriptor_template()
@ -551,12 +548,10 @@ namespace vk
return;
}
// FIXME: This sucks even if only used by interpreter. Do better.
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);
ensure((ptr->first + ptr->count) <= m_scratch_images_array.size());
m_descriptor_set.push(m_scratch_images_array.data() + ptr->first, ptr->count, type, idx);
ensure(m_descriptor_template[idx].descriptorCount == ptr->size());
m_descriptor_template[idx].pImageInfo = m_descriptor_set.store(*ptr);
return;
}
@ -611,7 +606,6 @@ namespace vk
m_descriptor_set.on_bind();
m_any_descriptors_dirty = false;
m_scratch_images_array.clear();
return m_descriptor_set.value();
}

View file

@ -113,13 +113,8 @@ namespace vk
VkShaderModule get_handle() const;
};
struct descriptor_array_ref_t
{
u32 first = 0;
u32 count = 0;
};
using descriptor_slot_t = std::variant<VkDescriptorImageInfo, VkDescriptorBufferInfo, VkBufferView, 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>;
struct descriptor_table_t
{
@ -140,8 +135,6 @@ namespace vk
std::vector<bool> m_descriptors_dirty;
bool m_any_descriptors_dirty = false;
rsx::simple_array< VkDescriptorImageInfo> m_scratch_images_array;
void init(VkDevice dev);
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, ::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 VkPipeline value() const { return m_pipeline; }

View file

@ -432,7 +432,7 @@ namespace vk
const VkDescriptorImageInfo* texture_ptr = sampled_images.data();
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);
}
}

View file

@ -164,6 +164,21 @@ namespace vk
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
const rsx::simple_array<WriteDescriptorSetT> peek() const { return m_pending_writes; }
u64 cache_id() const { return m_storage_cache_id; }