vk/data-heap: Implement a caching sliding window buffer view system

This commit is contained in:
kd-11 2026-04-26 20:41:07 +03:00 committed by kd-11
parent 82a4ff051e
commit 108276c076

View file

@ -4,6 +4,7 @@
#include "../VulkanAPI.h"
#include "buffer_object.h"
#include "commands.h"
#include "ex.h"
#include <memory>
#include <type_traits>
@ -34,6 +35,8 @@ namespace vk
std::unique_ptr<buffer> shadow;
std::vector<VkBufferCopy> dirty_ranges;
mutable utils::address_range64 m_cached_buffer_range{};
protected:
bool grow(usz size) override;
bool can_allocate_heap(const vk::memory_type_info& target_heap, usz size, int max_usage_percent);
@ -62,6 +65,35 @@ namespace vk
void sync(const vk::command_buffer& cmd);
template <usz Alignment>
VkDescriptorBufferInfoEx window(usz offset, usz range, u64 window_size) const
{
if (window_size > size())
{
// Driver specific. AMD allows viewing upto 4GB as UBO no problem.
return { *heap, 0, VK_WHOLE_SIZE };
}
if (utils::address_range64::start_length(offset, range).inside(m_cached_buffer_range)) [[ likely ]]
{
return { *heap, m_cached_buffer_range.start, m_cached_buffer_range.length() };
}
const u64 aligned_window_size = static_cast<u64>(window_size / Alignment) * Alignment;
const u64 start_partition = offset / aligned_window_size;
const u64 end_partition = (offset + range - 1) / aligned_window_size;
if (start_partition == end_partition) [[ likely ]]
{
m_cached_buffer_range = utils::address_range64::start_length(start_partition * aligned_window_size, aligned_window_size);
return { *heap, m_cached_buffer_range.start, m_cached_buffer_range.length() };
}
// We have a partition straddler. Invalidate caching and return exact range.
m_cached_buffer_range = {};
return { *heap, offset, range };
}
// Properties
bool is_dirty() const;
bool has_shadow() const { return !!shadow; }