From 8234bdb8f000e1dc2c11523ba596007dabe3f78a Mon Sep 17 00:00:00 2001 From: kd-11 Date: Sun, 10 Nov 2019 12:51:37 +0300 Subject: [PATCH] vk: Check for heap change events after a grow to avoid spec violations - Avoid referencing the old buffer in stale views. Status can be set globally if requested during heap creation. --- rpcs3/Emu/RSX/VK/VKGSRender.cpp | 20 +++++++++++++++----- rpcs3/Emu/RSX/VK/VKHelpers.cpp | 7 ++++++- rpcs3/Emu/RSX/VK/VKHelpers.h | 11 ++++++++--- rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp | 18 ++++++++++++++++++ 4 files changed, 47 insertions(+), 9 deletions(-) diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 5dc34cbd48..9b7bcfda1c 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -448,11 +448,11 @@ VKGSRender::VKGSRender() : GSRender() semaphore_info.sType = VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO; //VRAM allocation - m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000); + m_attrib_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_ATTRIB_RING_BUFFER_SIZE_M * 0x100000, "attrib buffer", 0x400000, VK_TRUE); m_fragment_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment env buffer"); m_vertex_env_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex env buffer"); m_fragment_texture_params_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment texture params buffer"); - m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex layout buffer"); + m_vertex_layout_ring_info.create(VK_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "vertex layout buffer", 0x10000, VK_TRUE); m_fragment_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_UBO_RING_BUFFER_SIZE_M * 0x100000, "fragment constants buffer"); m_transform_constants_ring_info.create(VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, VK_TRANSFORM_CONSTANTS_BUFFER_SIZE_M * 0x100000, "transform constants buffer"); m_index_buffer_ring_info.create(VK_BUFFER_USAGE_INDEX_BUFFER_BIT, VK_INDEX_RING_BUFFER_SIZE_M * 0x100000, "index buffer"); @@ -1092,7 +1092,17 @@ void VKGSRender::emit_geometry(u32 sub_index) // Allocate stream layout memory for this batch m_vertex_layout_stream_info.range = rsx::method_registers.current_draw_clause.pass_count() * 128; m_vertex_layout_stream_info.offset = m_vertex_layout_ring_info.alloc<256>(m_vertex_layout_stream_info.range); - // m_vertex_layout_stream_info.buffer = m_vertex_layout_ring_info.heap->value; + + if (vk::test_status_interrupt(vk::heap_changed)) + { + if (m_vertex_layout_storage && + m_vertex_layout_storage->info.buffer != m_vertex_layout_ring_info.heap->value) + { + m_current_frame->buffer_views_to_clean.push_back(std::move(m_vertex_layout_storage)); + } + + vk::clear_status_interrupt(vk::heap_changed); + } } else if (persistent_buffer != old_persistent_buffer || volatile_buffer != old_volatile_buffer) { @@ -2833,7 +2843,7 @@ void VKGSRender::close_and_submit_command_buffer(VkFence fence, VkSemaphore wait // Wait before sync block below rsx::g_dma_manager.sync(); - if (vk::test_status_interrupt(vk::heap_check)) + if (vk::test_status_interrupt(vk::heap_dirty)) { if (m_attrib_ring_info.dirty() || m_fragment_env_ring_info.dirty() || @@ -2864,7 +2874,7 @@ void VKGSRender::close_and_submit_command_buffer(VkFence fence, VkSemaphore wait VK_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT); } - vk::clear_status_interrupt(vk::heap_check); + vk::clear_status_interrupt(vk::heap_dirty); } // 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 86471a6b1a..279e4a2306 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.cpp +++ b/rpcs3/Emu/RSX/VK/VKHelpers.cpp @@ -169,6 +169,11 @@ namespace vk get_resource_manager()->dispose(heap); heap = std::make_unique(*device, aligned_new_size, memory_index, memory_flags, usage, 0); + if (notify_on_grow) + { + raise_status_interrupt(vk::heap_changed); + } + return true; } @@ -338,7 +343,7 @@ namespace vk { if (!g_upload_heap.heap) { - g_upload_heap.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 64 * 0x100000, "auxilliary upload heap"); + g_upload_heap.create(VK_BUFFER_USAGE_TRANSFER_SRC_BIT, 64 * 0x100000, "auxilliary upload heap", 0x100000); } return &g_upload_heap; diff --git a/rpcs3/Emu/RSX/VK/VKHelpers.h b/rpcs3/Emu/RSX/VK/VKHelpers.h index b16578520f..0378fca0c6 100644 --- a/rpcs3/Emu/RSX/VK/VKHelpers.h +++ b/rpcs3/Emu/RSX/VK/VKHelpers.h @@ -73,7 +73,8 @@ namespace vk enum runtime_state { uninterruptible = 1, - heap_check = 2 + heap_dirty = 2, + heap_changed = 3 }; enum class driver_vendor @@ -3407,6 +3408,8 @@ public: bool mapped = false; void *_ptr = nullptr; + bool notify_on_grow = false; + std::unique_ptr shadow; std::vector dirty_ranges; @@ -3420,7 +3423,7 @@ public: // Avoid mapping/unmapping to keep these drivers from stalling // NOTE2: HOST_CACHED flag does not keep the mapped ptr around in the driver either - void create(VkBufferUsageFlags usage, size_t size, const char *name = "unnamed", size_t guard = 0x10000) + void create(VkBufferUsageFlags usage, size_t size, const char *name, size_t guard = 0x10000, VkBool32 notify = VK_FALSE) { ::data_heap::init(size, name, guard); @@ -3441,7 +3444,9 @@ public: } heap = std::make_unique(*device, size, memory_index, memory_flags, usage, 0); + initial_size = size; + notify_on_grow = bool(notify); } void destroy() @@ -3470,7 +3475,7 @@ public: if (shadow) { dirty_ranges.push_back({offset, offset, size}); - raise_status_interrupt(runtime_state::heap_check); + raise_status_interrupt(runtime_state::heap_dirty); } return (u8*)_ptr + offset; diff --git a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp index a7a495e81f..316b1325fd 100644 --- a/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp +++ b/rpcs3/Emu/RSX/VK/VKVertexBuffers.cpp @@ -318,6 +318,24 @@ vk::vertex_upload_info VKGSRender::upload_vertex_data() } } + if (vk::test_status_interrupt(vk::heap_changed)) + { + // Check for validity + if (m_persistent_attribute_storage && + m_persistent_attribute_storage->info.buffer != m_attrib_ring_info.heap->value) + { + m_current_frame->buffer_views_to_clean.push_back(std::move(m_persistent_attribute_storage)); + } + + if (m_volatile_attribute_storage && + m_volatile_attribute_storage->info.buffer != m_attrib_ring_info.heap->value) + { + m_current_frame->buffer_views_to_clean.push_back(std::move(m_volatile_attribute_storage)); + } + + vk::clear_status_interrupt(vk::heap_changed); + } + if (persistent_range_base != UINT32_MAX) { if (!m_persistent_attribute_storage || !m_persistent_attribute_storage->in_range(persistent_range_base, required.first, persistent_range_base))