mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-01-02 23:00:20 +01:00
vk: Rewrite descriptor write template management
This commit is contained in:
parent
c4426b0f07
commit
3ee626ce3c
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
|
|
|
|||
Loading…
Reference in a new issue