mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 23:11:25 +12:00
vk: Restructure commandbuffer scoping to allow faults in vertex upload
- Defer renderpass open to allow recovery after fault in the middle of vertex upload
This commit is contained in:
parent
d0db7ca6bd
commit
360c0e9af6
1 changed files with 26 additions and 57 deletions
|
@ -693,14 +693,15 @@ bool VKGSRender::on_access_violation(u32 address, bool is_writing)
|
||||||
m_flush_requests.post(false);
|
m_flush_requests.post(false);
|
||||||
has_queue_ref = true;
|
has_queue_ref = true;
|
||||||
}
|
}
|
||||||
else if (!vk::is_uninterruptible())
|
|
||||||
{
|
|
||||||
//Flush primary cb queue to sync pending changes (e.g image transitions!)
|
|
||||||
flush_command_queue();
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
//LOG_ERROR(RSX, "Fault in uninterruptible code!");
|
if (vk::is_uninterruptible())
|
||||||
|
{
|
||||||
|
LOG_ERROR(RSX, "Fault in uninterruptible code!");
|
||||||
|
}
|
||||||
|
|
||||||
|
//Flush primary cb queue to sync pending changes (e.g image transitions!)
|
||||||
|
flush_command_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_queue_ref)
|
if (has_queue_ref)
|
||||||
|
@ -1135,6 +1136,13 @@ void VKGSRender::emit_geometry(u32 sub_index)
|
||||||
m_program->bind_uniform(m_vertex_layout_storage->value, VERTEX_BUFFERS_FIRST_BIND_SLOT + 2, m_current_frame->descriptor_set);
|
m_program->bind_uniform(m_vertex_layout_storage->value, VERTEX_BUFFERS_FIRST_BIND_SLOT + 2, m_current_frame->descriptor_set);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!m_render_pass_open)
|
||||||
|
{
|
||||||
|
vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline);
|
||||||
|
update_draw_state();
|
||||||
|
begin_render_pass();
|
||||||
|
}
|
||||||
|
|
||||||
// Bind the new set of descriptors for use with this draw call
|
// Bind the new set of descriptors for use with this draw call
|
||||||
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
vkCmdBindDescriptorSets(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline_layout, 0, 1, &m_current_frame->descriptor_set, 0, nullptr);
|
||||||
|
|
||||||
|
@ -1694,64 +1702,19 @@ void VKGSRender::end()
|
||||||
vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, primitive_emulated);
|
vk::get_appropriate_topology(rsx::method_registers.current_draw_clause.primitive, primitive_emulated);
|
||||||
|
|
||||||
// Apply write memory barriers
|
// Apply write memory barriers
|
||||||
if (true)//g_cfg.video.strict_rendering_mode)
|
if (ds) ds->write_barrier(*m_current_command_buffer);
|
||||||
|
|
||||||
|
for (auto &rtt : m_rtts.m_bound_render_targets)
|
||||||
{
|
{
|
||||||
if (ds) ds->write_barrier(*m_current_command_buffer);
|
if (auto surface = std::get<1>(rtt))
|
||||||
|
|
||||||
for (auto &rtt : m_rtts.m_bound_render_targets)
|
|
||||||
{
|
{
|
||||||
if (auto surface = std::get<1>(rtt))
|
surface->write_barrier(*m_current_command_buffer);
|
||||||
{
|
|
||||||
surface->write_barrier(*m_current_command_buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
begin_render_pass();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
begin_render_pass();
|
|
||||||
|
|
||||||
// Clear any 'dirty' surfaces - possible is a recycled cache surface is used
|
|
||||||
rsx::simple_array<VkClearAttachment> buffers_to_clear;
|
|
||||||
|
|
||||||
if (ds && ds->dirty())
|
|
||||||
{
|
|
||||||
// Clear this surface before drawing on it
|
|
||||||
VkClearValue clear_value = {};
|
|
||||||
clear_value.depthStencil = { 1.f, 255 };
|
|
||||||
buffers_to_clear.push_back({ vk::get_aspect_flags(ds->info.format), 0, clear_value });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u32 index = 0; index < m_draw_buffers.size(); ++index)
|
|
||||||
{
|
|
||||||
if (auto rtt = std::get<1>(m_rtts.m_bound_render_targets[index]))
|
|
||||||
{
|
|
||||||
if (rtt->dirty())
|
|
||||||
{
|
|
||||||
buffers_to_clear.push_back({ VK_IMAGE_ASPECT_COLOR_BIT, index, {} });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (UNLIKELY(!buffers_to_clear.empty()))
|
|
||||||
{
|
|
||||||
VkClearRect rect = { {{0, 0}, {m_draw_fbo->width(), m_draw_fbo->height()}}, 0, 1 };
|
|
||||||
vkCmdClearAttachments(*m_current_command_buffer, buffers_to_clear.size(),
|
|
||||||
buffers_to_clear.data(), 1, &rect);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final heap check...
|
// Final heap check...
|
||||||
check_heap_status(VK_HEAP_CHECK_VERTEX_STORAGE | VK_HEAP_CHECK_VERTEX_LAYOUT_STORAGE);
|
check_heap_status(VK_HEAP_CHECK_VERTEX_STORAGE | VK_HEAP_CHECK_VERTEX_LAYOUT_STORAGE);
|
||||||
|
|
||||||
// While vertex upload is an interruptible process, if we made it this far, there's no need to sync anything that occurs past this point
|
|
||||||
// Only textures are synchronized tightly with the GPU and they have been read back above
|
|
||||||
vk::enter_uninterruptible();
|
|
||||||
|
|
||||||
vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline);
|
|
||||||
update_draw_state();
|
|
||||||
|
|
||||||
u32 sub_index = 0;
|
u32 sub_index = 0;
|
||||||
rsx::method_registers.current_draw_clause.begin();
|
rsx::method_registers.current_draw_clause.begin();
|
||||||
do
|
do
|
||||||
|
@ -1760,8 +1723,8 @@ void VKGSRender::end()
|
||||||
}
|
}
|
||||||
while (rsx::method_registers.current_draw_clause.next());
|
while (rsx::method_registers.current_draw_clause.next());
|
||||||
|
|
||||||
|
// Close any open passes unconditionally
|
||||||
close_render_pass();
|
close_render_pass();
|
||||||
vk::leave_uninterruptible();
|
|
||||||
|
|
||||||
m_rtts.on_write(m_framebuffer_layout.color_write_enabled.data(), m_framebuffer_layout.zeta_write_enabled);
|
m_rtts.on_write(m_framebuffer_layout.color_write_enabled.data(), m_framebuffer_layout.zeta_write_enabled);
|
||||||
|
|
||||||
|
@ -2810,6 +2773,12 @@ 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_NULL_HANDLE, VK_NULL_HANDLE, VK_NULL_HANDLE, VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// End any active renderpasses; the caller should handle reopening
|
||||||
|
if (m_render_pass_open)
|
||||||
|
{
|
||||||
|
close_render_pass();
|
||||||
|
}
|
||||||
|
|
||||||
// End open queries. Flags will be automatically reset by the submit routine
|
// End open queries. Flags will be automatically reset by the submit routine
|
||||||
if (m_current_command_buffer->flags & vk::command_buffer::cb_has_open_query)
|
if (m_current_command_buffer->flags & vk::command_buffer::cb_has_open_query)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue