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
+23 -2
View File
@@ -19,6 +19,9 @@ namespace vk
const auto& memory_map = g_render_device->get_memory_mapping(); 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) if ((flags & heap_pool_low_latency) && g_cfg.video.vk.use_rebar_upload_heap)
{ {
// Prefer uploading to BAR if low latency is desired. // 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; 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; 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)
{
if (!vram_shadow_requested)
{ {
rsx_log.warning("Buffer usage %u is not heap-compatible using this driver, explicit staging buffer in use", usage); 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); 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; 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); 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; initial_size = size;
notify_on_grow = bool(notify); notify_on_grow = bool(notify);
} }
@@ -88,7 +98,7 @@ namespace vk
bool data_heap::grow(usz size) bool data_heap::grow(usz size)
{ {
// Create new heap. All sizes are aligned up by 64M, upto 1GiB // 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); usz aligned_new_size = utils::align(m_size + size, 64 * 0x100000);
if (aligned_new_size >= size_limit) if (aligned_new_size >= size_limit)
@@ -191,8 +201,19 @@ namespace vk
} }
if (shadow) if (shadow)
{
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 }); dirty_ranges.push_back({ offset, offset, size });
}
raise_status_interrupt(runtime_state::heap_dirty); raise_status_interrupt(runtime_state::heap_dirty);
} }
+6 -1
View File
@@ -14,7 +14,9 @@ namespace vk
enum data_heap_pool_flags enum data_heap_pool_flags
{ {
heap_pool_default = 0, heap_pool_default = 0,
heap_pool_low_latency = 1, 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 class data_heap : public ::data_heap
@@ -24,6 +26,8 @@ namespace vk
bool mapped = false; bool mapped = false;
void* _ptr = nullptr; void* _ptr = nullptr;
rsx::flags32_t m_flags = heap_pool_default;
bool notify_on_grow = false; bool notify_on_grow = false;
bool m_prefer_writethrough = false; bool m_prefer_writethrough = false;
@@ -60,6 +64,7 @@ namespace vk
// Properties // Properties
bool is_dirty() const; bool is_dirty() const;
bool has_shadow() const { return !!shadow; }
}; };
extern data_heap* get_upload_heap(); extern data_heap* get_upload_heap();