vk: Support more heap types
- Support for GPU shadow heap (manual flush) - Support for Fixed-Length data heaps
This commit is contained in:
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user