mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-01-16 16:21:03 +00:00
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.
This commit is contained in:
parent
5968427a2f
commit
8234bdb8f0
@ -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
|
||||
|
@ -169,6 +169,11 @@ namespace vk
|
||||
get_resource_manager()->dispose(heap);
|
||||
heap = std::make_unique<buffer>(*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;
|
||||
|
@ -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<buffer> shadow;
|
||||
std::vector<VkBufferCopy> 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<buffer>(*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;
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user