diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 510af1295c..b7d3d46d3b 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -270,7 +270,7 @@ void VKGSRender::load_texture_env() { if (tex.enabled()) { - check_heap_status(VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE); + check_heap_status(m_texture_upload_buffer_ring_info); *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); } else @@ -429,7 +429,7 @@ void VKGSRender::load_texture_env() { if (rsx::method_registers.vertex_textures[i].enabled()) { - check_heap_status(VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE); + check_heap_status(m_texture_upload_buffer_ring_info); *sampler_state = m_texture_cache.upload_texture(*m_current_command_buffer, tex, m_rtts); } else @@ -1141,7 +1141,12 @@ void VKGSRender::end() m_frame_stats.textures_upload_time += m_profiler.duration(); // Final heap check... - check_heap_status(VK_HEAP_CHECK_VERTEX_STORAGE | VK_HEAP_CHECK_VERTEX_LAYOUT_STORAGE); + check_heap_status( + { + std::ref(m_attrib_ring_info), + std::ref(m_index_buffer_ring_info), + std::ref(m_draw_indirect_count_ring_info) + }); u32 sub_index = 0; // RSX subdraw ID m_current_draw.subdraw_id = 0; // Host subdraw ID. Invalid RSX subdraws do not increment this value diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 85c23785c7..ad77bcc7fc 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1,4 +1,3 @@ -#include "Emu/RSX/VK/VKDataHeapManager.h" #include "stdafx.h" #include "../Overlays/overlay_compile_notification.h" #include "../Overlays/Shaders/shader_loading_dialog_native.h" @@ -1149,93 +1148,59 @@ void VKGSRender::notify_tile_unbound(u32 tile) } } -void VKGSRender::check_heap_status(u32 flags) +bool VKGSRender::check_heap_status(const vk::data_heap& heap) { - ensure(flags); - - bool heap_critical; - if (flags == VK_HEAP_CHECK_ALL) + if (heap.heap && heap.is_critical()) { - heap_critical = vk::data_heap_manager::any_critical(); + handle_heap_critical(); + return true; + } + + return false; +} + +bool VKGSRender::check_heap_status(std::initializer_list> heaps) +{ + for (const vk::data_heap& heap : heaps) + { + if (heap.heap && heap.is_critical()) + { + handle_heap_critical(); + return true; + } + } + + return false; +} + +void VKGSRender::handle_heap_critical() +{ + m_profiler.start(); + + vk::frame_context_t *target_frame = nullptr; + if (!m_queued_frames.empty()) + { + if (m_current_frame != &m_aux_frame_context) + { + target_frame = m_queued_frames.front(); + } + } + + if (target_frame == nullptr) + { + flush_command_queue(true); + m_vertex_cache->purge(); + + vk::data_heap_manager::reset_heap_allocations(); + m_last_heap_sync_time = rsx::get_shared_tag(); } else { - heap_critical = false; - do - { - const u32 test = 1u << std::countr_zero(flags); - switch (flags & test) - { - case 0: - break; - case VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE: - heap_critical = m_texture_upload_buffer_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_VERTEX_STORAGE: - heap_critical = m_attrib_ring_info.is_critical() || - m_index_buffer_ring_info.is_critical() || - (m_draw_indirect_count_ring_info.heap - ? m_draw_indirect_count_ring_info.is_critical() - : false); - break; - case VK_HEAP_CHECK_VERTEX_ENV_STORAGE: - heap_critical = m_vertex_env_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE: - heap_critical = m_fragment_env_ring_info.is_critical() || m_raster_env_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_TEXTURE_ENV_STORAGE: - heap_critical = m_fragment_texture_params_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_VERTEX_LAYOUT_STORAGE: - heap_critical = m_vertex_layout_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE: - heap_critical = (current_vertex_program.ctrl & RSX_SHADER_CONTROL_INSTANCED_CONSTANTS) - ? m_instancing_buffer_ring_info.is_critical() - : m_transform_constants_ring_info.is_critical(); - break; - case VK_HEAP_CHECK_FRAGMENT_CONSTANTS_STORAGE: - heap_critical = m_fragment_constants_ring_info.is_critical(); - break; - default: - fmt::throw_exception("Unexpected heap flag set! (0x%X)", test); - } - - flags &= ~test; - } - while (flags && !heap_critical); + // Flush the frame context + frame_context_cleanup(target_frame); } - if (heap_critical) - { - m_profiler.start(); - - vk::frame_context_t *target_frame = nullptr; - if (!m_queued_frames.empty()) - { - if (m_current_frame != &m_aux_frame_context) - { - target_frame = m_queued_frames.front(); - } - } - - if (target_frame == nullptr) - { - flush_command_queue(true); - m_vertex_cache->purge(); - - vk::data_heap_manager::reset_heap_allocations(); - m_last_heap_sync_time = rsx::get_shared_tag(); - } - else - { - // Flush the frame context - frame_context_cleanup(target_frame); - } - - m_frame_stats.flip_time += m_profiler.duration(); - } + m_frame_stats.flip_time += m_profiler.duration(); } void VKGSRender::check_present_status() @@ -2041,7 +2006,7 @@ void VKGSRender::load_program_env() if (update_vertex_env) { - check_heap_status(VK_HEAP_CHECK_VERTEX_ENV_STORAGE); + check_heap_status(m_vertex_env_ring_info); // Vertex state const auto mem = m_vertex_env_ring_info.static_alloc<256>(); @@ -2108,7 +2073,7 @@ void VKGSRender::load_program_env() if (update_fragment_constants && !m_shader_interpreter.is_interpreter(m_program)) { - check_heap_status(VK_HEAP_CHECK_FRAGMENT_CONSTANTS_STORAGE); + check_heap_status(m_fragment_constants_ring_info); // Fragment constants if (fragment_constants_size) @@ -2130,7 +2095,7 @@ void VKGSRender::load_program_env() if (update_fragment_env) { - check_heap_status(VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE); + check_heap_status(m_fragment_env_ring_info); auto mem = m_fragment_env_ring_info.static_alloc<256>(); auto buf = m_fragment_env_ring_info.map(mem, 32); @@ -2142,7 +2107,7 @@ void VKGSRender::load_program_env() if (update_fragment_texture_env) { - check_heap_status(VK_HEAP_CHECK_TEXTURE_ENV_STORAGE); + check_heap_status(m_fragment_texture_params_ring_info); auto mem = m_fragment_texture_params_ring_info.static_alloc<256, 768>(); auto buf = m_fragment_texture_params_ring_info.map(mem, 768); @@ -2154,7 +2119,7 @@ void VKGSRender::load_program_env() if (update_raster_env) { - check_heap_status(VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE); + check_heap_status(m_raster_env_ring_info); auto mem = m_raster_env_ring_info.static_alloc<256>(); auto buf = m_raster_env_ring_info.map(mem, 128); @@ -2272,7 +2237,10 @@ void VKGSRender::upload_transform_constants(const rsx::io_buffer& buffer) if (transform_constants_size) { - check_heap_status(VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE); + auto& data_source = (current_vertex_program.ctrl & RSX_SHADER_CONTROL_INSTANCED_CONSTANTS) + ? m_instancing_buffer_ring_info + : m_transform_constants_ring_info; + check_heap_status(data_source); buffer.reserve(transform_constants_size); auto buf = buffer.data(); @@ -2762,7 +2730,7 @@ bool VKGSRender::scaled_image_from_memory(const rsx::blit_src_info& src, const r return false; // Verify enough memory exists before attempting to handle data transfer - check_heap_status(VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE); + check_heap_status(m_texture_upload_buffer_ring_info); if (m_texture_cache.blit(src, dst, interpolate, m_rtts, *m_current_command_buffer)) { diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 19702ce314..91cfa4dfb1 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -20,6 +20,8 @@ #include "Emu/RSX/GSRender.h" #include "Emu/RSX/Host/RSXDMAWriter.h" +#include +#include using namespace vk::vmm_allocation_pool_; // clang workaround. using namespace vk::upscaling_flags_; // ditto @@ -32,21 +34,6 @@ namespace vk class VKGSRender : public GSRender, public ::rsx::reports::ZCULL_control { private: - enum - { - VK_HEAP_CHECK_TEXTURE_UPLOAD_STORAGE = 0x1, - VK_HEAP_CHECK_VERTEX_STORAGE = 0x2, - VK_HEAP_CHECK_VERTEX_ENV_STORAGE = 0x4, - VK_HEAP_CHECK_FRAGMENT_ENV_STORAGE = 0x8, - VK_HEAP_CHECK_TEXTURE_ENV_STORAGE = 0x10, - VK_HEAP_CHECK_VERTEX_LAYOUT_STORAGE = 0x20, - VK_HEAP_CHECK_TRANSFORM_CONSTANTS_STORAGE = 0x40, - VK_HEAP_CHECK_FRAGMENT_CONSTANTS_STORAGE = 0x80, - - VK_HEAP_CHECK_MAX_ENUM = VK_HEAP_CHECK_FRAGMENT_CONSTANTS_STORAGE, - VK_HEAP_CHECK_ALL = 0xFF, - }; - enum frame_context_state : u32 { dirty = 1 @@ -232,7 +219,9 @@ private: void update_draw_state(); - void check_heap_status(u32 flags = VK_HEAP_CHECK_ALL); + void handle_heap_critical(); + bool check_heap_status(const vk::data_heap& heap); + bool check_heap_status(std::initializer_list> heaps); void check_present_status(); VkDescriptorSet allocate_descriptor_set();