diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 080d76e5ab..ce50a28523 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -2831,8 +2831,7 @@ void VKGSRender::close_and_submit_command_buffer(VkFence fence, VkSemaphore wait // Wait before sync block below rsx::g_dma_manager.sync(); - // TODO: Better check for shadowed memory - //if (m_attrib_ring_info.shadow) + if (vk::test_status_interrupt(vk::heap_check)) { if (m_attrib_ring_info.dirty() || m_fragment_env_ring_info.dirty() || @@ -2862,6 +2861,8 @@ void VKGSRender::close_and_submit_command_buffer(VkFence fence, VkSemaphore wait m_secondary_command_buffer.submit(m_swapchain->get_graphics_queue(), VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); } + + vk::clear_status_interrupt(vk::heap_check); } // End any active renderpasses; the caller should handle reopening diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.cpp b/rpcs3/Emu/RSX/VK/VKHelpers.cpp index 6b794d4990..86471a6b1a 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -78,7 +78,7 @@ namespace vk VkSampler g_null_sampler = nullptr; - atomic_t g_cb_no_interrupt_flag { false }; + rsx::atomic_bitmask_t g_runtime_state; // Driver compatibility workarounds VkFlags g_heap_compatible_buffer_types = 0; @@ -426,7 +426,7 @@ namespace vk void set_current_renderer(const vk::render_device &device) { g_current_renderer = &device; - g_cb_no_interrupt_flag.store(false); + g_runtime_state.clear(); g_drv_no_primitive_restart_flag = false; g_drv_sanitize_fp_values = false; g_drv_disable_fence_reset = false; @@ -780,19 +780,34 @@ namespace vk image->current_layout = new_layout; } + void raise_status_interrupt(runtime_state status) + { + g_runtime_state |= status; + } + + void clear_status_interrupt(runtime_state status) + { + g_runtime_state.clear(status); + } + + bool test_status_interrupt(runtime_state status) + { + return g_runtime_state & status; + } + void enter_uninterruptible() { - g_cb_no_interrupt_flag = true; + raise_status_interrupt(runtime_state::uninterruptible); } void leave_uninterruptible() { - g_cb_no_interrupt_flag = false; + clear_status_interrupt(runtime_state::uninterruptible); } bool is_uninterruptible() { - return g_cb_no_interrupt_flag; + return test_status_interrupt(runtime_state::uninterruptible); } void advance_completed_frame_counter() diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index 2fff476b55..341e806c13 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -70,6 +70,11 @@ namespace vk void *pUserData); //VkAllocationCallbacks default_callbacks(); + enum runtime_state + { + uninterruptible = 1, + heap_check = 2 + }; enum class driver_vendor { @@ -203,7 +208,9 @@ namespace vk VkPipelineStageFlags src_stage, VkPipelineStageFlags dst_stage, VkAccessFlags src_mask, VkAccessFlags dst_mask, const VkImageSubresourceRange& range); - //Manage 'uininterruptible' state where secondary operations (e.g violation handlers) will have to wait + void raise_status_interrupt(runtime_state status); + void clear_status_interrupt(runtime_state status); + bool test_status_interrupt(runtime_state status); void enter_uninterruptible(); void leave_uninterruptible(); bool is_uninterruptible(); @@ -3452,6 +3459,7 @@ public: if (shadow) { dirty_ranges.push_back({offset, offset, size}); + raise_status_interrupt(runtime_state::heap_check); } return (u8*)_ptr + offset;