diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 504add31fd..135b7c31b0 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -623,6 +623,8 @@ void GLGSRender::end() } } while (rsx::method_registers.current_draw_clause.next()); + rsx::method_registers.current_draw_clause.post_execute_cleanup(); + m_rtts.on_write(); m_attrib_ring_buffer->notify(); diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index 087dc4ad96..196317df65 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1682,6 +1682,8 @@ void VKGSRender::end() } while (rsx::method_registers.current_draw_clause.next()); + rsx::method_registers.current_draw_clause.post_execute_cleanup(); + close_render_pass(); vk::leave_uninterruptible(); diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 80a96232f7..32d5c8906f 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -632,7 +632,9 @@ namespace rsx 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 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) { - 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 method_registers.decode(reg, method_registers.register_previous_value); diff --git a/rpcs3/Emu/RSX/rsx_methods.h b/rpcs3/Emu/RSX/rsx_methods.h index 39b9620f03..383b6aac76 100644 --- a/rpcs3/Emu/RSX/rsx_methods.h +++ b/rpcs3/Emu/RSX/rsx_methods.h @@ -277,7 +277,7 @@ namespace rsx 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 @@ -288,7 +288,15 @@ namespace rsx 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) @@ -339,10 +347,36 @@ namespace rsx 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; } + /** + * 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 */