rsx: Fix insertion of execution barriers

- Ignore barriers inserted after BEGIN but before any draw commands are emitted
- Properly process tail barriers inserted before END but after draw commands are submitted
- Ignore execution barriers with no effect (same register value written)
This commit is contained in:
kd-11 2018-11-13 13:12:18 +03:00 committed by kd-11
parent 1d19f71a46
commit 8a186bb97e
4 changed files with 47 additions and 5 deletions

View file

@ -623,6 +623,8 @@ void GLGSRender::end()
} }
} while (rsx::method_registers.current_draw_clause.next()); } while (rsx::method_registers.current_draw_clause.next());
rsx::method_registers.current_draw_clause.post_execute_cleanup();
m_rtts.on_write(); m_rtts.on_write();
m_attrib_ring_buffer->notify(); m_attrib_ring_buffer->notify();

View file

@ -1682,6 +1682,8 @@ void VKGSRender::end()
} }
while (rsx::method_registers.current_draw_clause.next()); while (rsx::method_registers.current_draw_clause.next());
rsx::method_registers.current_draw_clause.post_execute_cleanup();
close_render_pass(); close_render_pass();
vk::leave_uninterruptible(); vk::leave_uninterruptible();

View file

@ -632,7 +632,9 @@ namespace rsx
void set_vertex_base_offset(thread* rsx, u32 reg, u32 arg) void set_vertex_base_offset(thread* rsx, u32 reg, u32 arg)
{ {
if (rsx->in_begin_end) if (rsx->in_begin_end &&
!rsx::method_registers.current_draw_clause.empty() &&
reg != method_registers.register_previous_value)
{ {
// Revert change to queue later // Revert change to queue later
method_registers.decode(reg, method_registers.register_previous_value); method_registers.decode(reg, method_registers.register_previous_value);
@ -644,7 +646,9 @@ namespace rsx
void set_index_base_offset(thread* rsx, u32 reg, u32 arg) void set_index_base_offset(thread* rsx, u32 reg, u32 arg)
{ {
if (rsx->in_begin_end) if (rsx->in_begin_end &&
!rsx::method_registers.current_draw_clause.empty() &&
reg != method_registers.register_previous_value)
{ {
// Revert change to queue later // Revert change to queue later
method_registers.decode(reg, method_registers.register_previous_value); method_registers.decode(reg, method_registers.register_previous_value);

View file

@ -277,7 +277,7 @@ namespace rsx
bool empty() const bool empty() const
{ {
return (draw_command_ranges.empty() && inline_vertex_array.empty()); return (command == rsx::draw_command::inlined_array) ? inline_vertex_array.empty() : draw_command_ranges.empty();
} }
u32 pass_count() const u32 pass_count() const
@ -288,7 +288,15 @@ namespace rsx
return 1u; return 1u;
} }
return (u32)draw_command_ranges.size(); u32 count = (u32)draw_command_ranges.size();
if (draw_command_ranges.back().count == 0)
{
// Dangling barrier
verify(HERE), count > 1;
count--;
}
return count;
} }
void reset(rsx::primitive_type type) void reset(rsx::primitive_type type)
@ -339,10 +347,36 @@ namespace rsx
return false; return false;
} }
verify(HERE), draw_command_ranges[current_range_index].count != 0; if (draw_command_ranges[current_range_index].count == 0)
{
// Dangling execution barrier
verify(HERE), current_range_index > 0 && (current_range_index + 1) == draw_command_ranges.size();
current_range_index = 0;
return false;
}
return true; return true;
} }
/**
* Only call this once after the draw clause has been fully consumed to reconcile any conflicts
*/
void post_execute_cleanup()
{
verify(HERE), current_range_index == 0;
if (draw_command_ranges.size() > 1)
{
if (draw_command_ranges.back().count == 0)
{
// Dangling execution barrier
current_range_index = draw_command_ranges.size() - 1;
execute_pipeline_dependencies();
current_range_index = 0;
}
}
}
/** /**
* Executes commands reqiured to make the current draw state valid * Executes commands reqiured to make the current draw state valid
*/ */