vk: Support more heap types

- Support for GPU shadow heap (manual flush)
- Support for Fixed-Length data heaps
This commit is contained in:
kd-11
2026-04-25 21:09:59 +03:00
committed by kd-11
parent d40a4ee04e
commit 28ab991302
2 changed files with 32 additions and 6 deletions
+25 -4
View File
@@ -19,6 +19,9 @@ namespace vk
const auto& memory_map = g_render_device->get_memory_mapping();
ensure(std::popcount(flags & (heap_pool_force_vram_shadow | heap_pool_low_latency)) <= 1,
"Invalid data heap flag combination detected");
if ((flags & heap_pool_low_latency) && g_cfg.video.vk.use_rebar_upload_heap)
{
// Prefer uploading to BAR if low latency is desired.
@@ -39,9 +42,15 @@ namespace vk
VkFlags memory_flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
auto memory_index = m_prefer_writethrough ? memory_map.device_bar : memory_map.host_visible_coherent;
if (!(get_heap_compatible_buffer_types() & usage))
const bool vram_shadow_requested = !!(flags & heap_pool_force_vram_shadow);
const bool use_shadow = vram_shadow_requested || !(get_heap_compatible_buffer_types() & usage);
if (use_shadow)
{
rsx_log.warning("Buffer usage %u is not heap-compatible using this driver, explicit staging buffer in use", usage);
if (!vram_shadow_requested)
{
rsx_log.warning("Buffer usage %u is not heap-compatible using this driver, explicit staging buffer in use", usage);
}
shadow = std::make_unique<buffer>(*g_render_device, size, memory_index, memory_flags, VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 0, VMM_ALLOCATION_POOL_SYSTEM);
usage |= VK_BUFFER_USAGE_TRANSFER_DST_BIT;
@@ -70,6 +79,7 @@ namespace vk
heap = std::make_unique<buffer>(*g_render_device, size, memory_map.host_visible_coherent, memory_flags, usage, 0, VMM_ALLOCATION_POOL_SYSTEM);
}
m_flags = flags;
initial_size = size;
notify_on_grow = bool(notify);
}
@@ -88,7 +98,7 @@ namespace vk
bool data_heap::grow(usz size)
{
// Create new heap. All sizes are aligned up by 64M, upto 1GiB
const usz size_limit = 1024 * 0x100000;
const usz size_limit = (m_flags & heap_pool_fixed_size) ? initial_size : 1024 * 0x100000;
usz aligned_new_size = utils::align(m_size + size, 64 * 0x100000);
if (aligned_new_size >= size_limit)
@@ -192,7 +202,18 @@ namespace vk
if (shadow)
{
dirty_ranges.push_back({ offset, offset, size });
bool insert = true;
if (!dirty_ranges.empty() && (dirty_ranges.back().dstOffset + dirty_ranges.back().size) == offset) [[ likely ]]
{
dirty_ranges.back().size += size;
insert = false;
}
if (insert)
{
dirty_ranges.push_back({ offset, offset, size });
}
raise_status_interrupt(runtime_state::heap_dirty);
}
+7 -2
View File
@@ -13,8 +13,10 @@ namespace vk
{
enum data_heap_pool_flags
{
heap_pool_default = 0,
heap_pool_low_latency = 1,
heap_pool_default = 0,
heap_pool_low_latency = (1 << 0),
heap_pool_fixed_size = (1 << 1),
heap_pool_force_vram_shadow = (1 << 2),
};
class data_heap : public ::data_heap
@@ -24,6 +26,8 @@ namespace vk
bool mapped = false;
void* _ptr = nullptr;
rsx::flags32_t m_flags = heap_pool_default;
bool notify_on_grow = false;
bool m_prefer_writethrough = false;
@@ -60,6 +64,7 @@ namespace vk
// Properties
bool is_dirty() const;
bool has_shadow() const { return !!shadow; }
};
extern data_heap* get_upload_heap();