From 74aa74f9eb207cfd355aafb9a3e8809b5ec2e590 Mon Sep 17 00:00:00 2001 From: kd-11 Date: Mon, 31 Mar 2025 12:55:58 +0300 Subject: [PATCH] vk: Refactor the heap manager --- rpcs3/Emu/CMakeLists.txt | 2 +- ...ntextManager.cpp => VKDataHeapManager.cpp} | 25 ++++++++++++- ...meContextManager.h => VKDataHeapManager.h} | 8 +++- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 37 +++++-------------- rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp | 6 +-- rpcs3/Emu/RSX/VK/VKPresent.cpp | 12 +----- rpcs3/Emu/RSX/VK/vkutils/device.cpp | 1 + rpcs3/Emu/RSX/VK/vkutils/device.h | 2 + rpcs3/VKGSRender.vcxproj | 4 +- rpcs3/VKGSRender.vcxproj.filters | 4 +- 10 files changed, 52 insertions(+), 49 deletions(-) rename rpcs3/Emu/RSX/VK/{VKFrameContextManager.cpp => VKDataHeapManager.cpp} (75%) rename rpcs3/Emu/RSX/VK/{VKFrameContextManager.h => VKDataHeapManager.h} (78%) diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index 0f531f9825..f8476746ac 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -627,12 +627,12 @@ if(TARGET 3rdparty_vulkan) RSX/VK/VKCommonDecompiler.cpp RSX/VK/VKCommonPipelineLayout.cpp RSX/VK/VKCompute.cpp + RSX/VK/VKDataHeapManager.cpp RSX/VK/VKDMA.cpp RSX/VK/VKDraw.cpp RSX/VK/VKFormats.cpp RSX/VK/VKFragmentProgram.cpp RSX/VK/VKFramebuffer.cpp - RSX/VK/VKFrameContextManager.cpp RSX/VK/VKGSRender.cpp RSX/VK/VKHelpers.cpp RSX/VK/VKMemAlloc.cpp diff --git a/rpcs3/Emu/RSX/VK/VKFrameContextManager.cpp b/rpcs3/Emu/RSX/VK/VKDataHeapManager.cpp similarity index 75% rename from rpcs3/Emu/RSX/VK/VKFrameContextManager.cpp rename to rpcs3/Emu/RSX/VK/VKDataHeapManager.cpp index c163525b16..b3d797d67f 100644 --- a/rpcs3/Emu/RSX/VK/VKFrameContextManager.cpp +++ b/rpcs3/Emu/RSX/VK/VKDataHeapManager.cpp @@ -1,10 +1,10 @@ #include "stdafx.h" -#include "VKFrameContextManager.h" +#include "VKDataHeapManager.h" #include "vkutils/data_heap.h" #include -namespace vk::frame_context_manager +namespace vk::data_heap_manager { std::unordered_set g_managed_heaps; @@ -46,6 +46,27 @@ namespace vk::frame_context_manager } } + void reset_heap_allocations() + { + for (auto& heap : g_managed_heaps) + { + heap->reset_allocation_stats(); + } + } + + bool any_critical() + { + for (auto& heap : g_managed_heaps) + { + if (heap->is_critical()) + { + return true; + } + } + + return false; + } + void reset() { for (auto& heap : g_managed_heaps) diff --git a/rpcs3/Emu/RSX/VK/VKFrameContextManager.h b/rpcs3/Emu/RSX/VK/VKDataHeapManager.h similarity index 78% rename from rpcs3/Emu/RSX/VK/VKFrameContextManager.h rename to rpcs3/Emu/RSX/VK/VKDataHeapManager.h index d612b829f9..54a7adf422 100644 --- a/rpcs3/Emu/RSX/VK/VKFrameContextManager.h +++ b/rpcs3/Emu/RSX/VK/VKDataHeapManager.h @@ -8,7 +8,7 @@ namespace vk { class data_heap; - namespace frame_context_manager + namespace data_heap_manager { using managed_heap_snapshot_t = std::unordered_map; @@ -24,6 +24,12 @@ namespace vk // Synchronize heap with snapshot void restore_snapshot(const managed_heap_snapshot_t& snapshot); + // Reset all managed heap allocations + void reset_heap_allocations(); + + // Check if any managed heap is in critical state + bool any_critical(); + // Cleanup void reset(); } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index fb30b04662..9a8c293e21 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -527,7 +527,7 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) m_raster_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "raster env buffer"); m_instancing_buffer_ring_info.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "instancing data buffer"); - vk::frame_context_manager::register_ring_buffers + vk::data_heap_manager::register_ring_buffers ({ std::ref(m_attrib_ring_info), std::ref(m_fragment_env_ring_info), @@ -538,8 +538,6 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) std::ref(m_transform_constants_ring_info), std::ref(m_index_buffer_ring_info), std::ref(m_texture_upload_buffer_ring_info), - std::ref(m_vertex_instructions_buffer), - std::ref(m_fragment_instructions_buffer), std::ref(m_raster_env_ring_info), std::ref(m_instancing_buffer_ring_info) }); @@ -550,6 +548,12 @@ VKGSRender::VKGSRender(utils::serial* ar) noexcept : GSRender(ar) { m_vertex_instructions_buffer.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 64 * 0x100000, "vertex instructions buffer", 512 * 16); m_fragment_instructions_buffer.create(VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, 64 * 0x100000, "fragment instructions buffer", 2048); + + vk::data_heap_manager::register_ring_buffers + ({ + std::ref(m_vertex_instructions_buffer), + std::ref(m_fragment_instructions_buffer) + }); } // Initialize optional allocation information with placeholders @@ -820,7 +824,7 @@ VKGSRender::~VKGSRender() m_upscaler.reset(); // Heaps - vk::frame_context_manager::reset(); + vk::data_heap_manager::reset(); // Fallback bindables null_buffer.reset(); @@ -1149,17 +1153,7 @@ void VKGSRender::check_heap_status(u32 flags) bool heap_critical; if (flags == VK_HEAP_CHECK_ALL) { - heap_critical = m_attrib_ring_info.is_critical() || - m_texture_upload_buffer_ring_info.is_critical() || - m_fragment_env_ring_info.is_critical() || - m_vertex_env_ring_info.is_critical() || - m_fragment_texture_params_ring_info.is_critical() || - m_vertex_layout_ring_info.is_critical() || - m_fragment_constants_ring_info.is_critical() || - m_transform_constants_ring_info.is_critical() || - m_index_buffer_ring_info.is_critical() || - m_raster_env_ring_info.is_critical() || - m_instancing_buffer_ring_info.is_critical(); + heap_critical = vk::data_heap_manager::any_critical(); } else { @@ -1226,18 +1220,7 @@ void VKGSRender::check_heap_status(u32 flags) flush_command_queue(true); m_vertex_cache->purge(); - m_index_buffer_ring_info.reset_allocation_stats(); - m_fragment_env_ring_info.reset_allocation_stats(); - m_vertex_env_ring_info.reset_allocation_stats(); - m_fragment_texture_params_ring_info.reset_allocation_stats(); - m_vertex_layout_ring_info.reset_allocation_stats(); - m_fragment_constants_ring_info.reset_allocation_stats(); - m_transform_constants_ring_info.reset_allocation_stats(); - m_attrib_ring_info.reset_allocation_stats(); - m_texture_upload_buffer_ring_info.reset_allocation_stats(); - m_raster_env_ring_info.reset_allocation_stats(); - m_instancing_buffer_ring_info.reset_allocation_stats(); - m_current_frame->reset_heap_ptrs(); + vk::data_heap_manager::reset_heap_allocations(); m_last_heap_sync_time = rsx::get_shared_tag(); } else diff --git a/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp b/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp index 2aa62c858c..bc29c0eaf2 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp +++ b/rpcs3/Emu/RSX/VK/VKGSRenderTypes.hpp @@ -2,7 +2,7 @@ #include "vkutils/commands.h" #include "vkutils/descriptors.h" -#include "VKFrameContextManager.h" +#include "VKDataHeapManager.h" #include "VKResourceManager.h" #include "Emu/RSX/Common/simple_array.hpp" @@ -187,7 +187,7 @@ namespace vk u32 present_image = -1; command_buffer_chunk* swap_command_buffer = nullptr; - frame_context_manager::managed_heap_snapshot_t heap_snapshot; + data_heap_manager::managed_heap_snapshot_t heap_snapshot; u64 last_frame_sync_time = 0; // Copy shareable information @@ -209,7 +209,7 @@ namespace vk void tag_frame_end() { - heap_snapshot = frame_context_manager::get_heap_snapshot(); + heap_snapshot = data_heap_manager::get_heap_snapshot(); last_frame_sync_time = rsx::get_shared_tag(); } diff --git a/rpcs3/Emu/RSX/VK/VKPresent.cpp b/rpcs3/Emu/RSX/VK/VKPresent.cpp index 1d743f170a..4f4d868537 100644 --- a/rpcs3/Emu/RSX/VK/VKPresent.cpp +++ b/rpcs3/Emu/RSX/VK/VKPresent.cpp @@ -209,7 +209,6 @@ void VKGSRender::frame_context_cleanup(vk::frame_context_t *ctx) } // Resource cleanup. - // TODO: This is some outdated crap. { if (m_overlay_manager && m_overlay_manager->has_dirty()) { @@ -235,21 +234,12 @@ void VKGSRender::frame_context_cleanup(vk::frame_context_t *ctx) ctx->buffer_views_to_clean.clear(); - const auto shadermode = g_cfg.video.shadermode.get(); - - if (shadermode == shader_mode::async_with_interpreter || shadermode == shader_mode::interpreter_only) - { - // TODO: This is jank AF - m_vertex_instructions_buffer.reset_allocation_stats(); - m_fragment_instructions_buffer.reset_allocation_stats(); - } - if (ctx->last_frame_sync_time > m_last_heap_sync_time) { m_last_heap_sync_time = ctx->last_frame_sync_time; // Heap cleanup; deallocates memory consumed by the frame if it is still held - vk::frame_context_manager::restore_snapshot(ctx->heap_snapshot); + vk::data_heap_manager::restore_snapshot(ctx->heap_snapshot); } } diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.cpp b/rpcs3/Emu/RSX/VK/vkutils/device.cpp index 35c94e35cd..58a82a767b 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.cpp +++ b/rpcs3/Emu/RSX/VK/vkutils/device.cpp @@ -124,6 +124,7 @@ namespace vk optional_features_support.sampler_mirror_clamped = device_extensions.is_supported(VK_KHR_SAMPLER_MIRROR_CLAMP_TO_EDGE_EXTENSION_NAME); optional_features_support.synchronization_2 = device_extensions.is_supported(VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME); optional_features_support.unrestricted_depth_range = device_extensions.is_supported(VK_EXT_DEPTH_RANGE_UNRESTRICTED_EXTENSION_NAME); + optional_features_support.multidraw_indirect = device_extensions.is_supported(VK_KHR_DRAW_INDIRECT_COUNT_EXTENSION_NAME); optional_features_support.debug_utils = instance_extensions.is_supported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME); optional_features_support.surface_capabilities_2 = instance_extensions.is_supported(VK_KHR_GET_PHYSICAL_DEVICE_PROPERTIES_2_EXTENSION_NAME); diff --git a/rpcs3/Emu/RSX/VK/vkutils/device.h b/rpcs3/Emu/RSX/VK/vkutils/device.h index febd132d7e..bfb141c584 100644 --- a/rpcs3/Emu/RSX/VK/vkutils/device.h +++ b/rpcs3/Emu/RSX/VK/vkutils/device.h @@ -93,6 +93,7 @@ namespace vk bool unrestricted_depth_range = false; bool extended_device_fault = false; bool texture_compression_bc = false; + bool multidraw_indirect = false; } optional_features_support; friend class render_device; @@ -192,6 +193,7 @@ namespace vk bool get_synchronization2_support() const { return pgpu->optional_features_support.synchronization_2; } bool get_extended_device_fault_support() const { return pgpu->optional_features_support.extended_device_fault; } bool get_texture_compression_bc_support() const { return pgpu->optional_features_support.texture_compression_bc; } + bool get_multidraw_indirect_support() const { return pgpu->optional_features_support.multidraw_indirect; } u64 get_descriptor_update_after_bind_support() const { return pgpu->descriptor_indexing_support.update_after_bind_mask; } u32 get_descriptor_max_draw_calls() const { return pgpu->descriptor_max_draw_calls; } diff --git a/rpcs3/VKGSRender.vcxproj b/rpcs3/VKGSRender.vcxproj index c70985ddd1..99c1b8594f 100644 --- a/rpcs3/VKGSRender.vcxproj +++ b/rpcs3/VKGSRender.vcxproj @@ -19,11 +19,11 @@ + - @@ -74,12 +74,12 @@ + - diff --git a/rpcs3/VKGSRender.vcxproj.filters b/rpcs3/VKGSRender.vcxproj.filters index 0edd3d0416..18f61ab147 100644 --- a/rpcs3/VKGSRender.vcxproj.filters +++ b/rpcs3/VKGSRender.vcxproj.filters @@ -2,12 +2,12 @@ + - @@ -84,11 +84,11 @@ + -