diff --git a/rpcs3/Emu/RSX/VK/VKDraw.cpp b/rpcs3/Emu/RSX/VK/VKDraw.cpp index 8a5440c75c..a168905a56 100644 --- a/rpcs3/Emu/RSX/VK/VKDraw.cpp +++ b/rpcs3/Emu/RSX/VK/VKDraw.cpp @@ -803,14 +803,31 @@ void VKGSRender::emit_geometry(u32 sub_index) m_program->bind_uniform(m_vertex_layout_storage->value, binding_table.vertex_buffers_first_bind_slot + 2, m_current_frame->descriptor_set); } - if (!m_current_subdraw_id++) + bool reload_state = (!m_current_subdraw_id++); + vk::renderpass_op(*m_current_command_buffer, [&](VkCommandBuffer cmd, VkRenderPass pass, VkFramebuffer fbo) { + if (get_render_pass() == pass && m_draw_fbo->value == fbo) + { + // Nothing to do + return; + } + + if (pass) + { + // Subpass mismatch, end it before proceeding + vk::end_renderpass(cmd); + } + + reload_state = true; + }); + + if (reload_state) + { + vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline); + update_draw_state(); begin_render_pass(); - // Bind pipeline after starting the renderpass to work around some validation layer spam about format mismatch - vkCmdBindPipeline(*m_current_command_buffer, VK_PIPELINE_BIND_POINT_GRAPHICS, m_program->pipeline); - if (cond_render_ctrl.hw_cond_active && m_device->get_conditional_render_support()) { // It is inconvenient that conditional rendering breaks other things like compute dispatch diff --git a/rpcs3/Emu/RSX/VK/VKRenderPass.cpp b/rpcs3/Emu/RSX/VK/VKRenderPass.cpp index a8d647e16b..355ce58eca 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderPass.cpp +++ b/rpcs3/Emu/RSX/VK/VKRenderPass.cpp @@ -272,4 +272,10 @@ namespace vk { return g_current_renderpass[cmd].pass != VK_NULL_HANDLE; } + + void renderpass_op(VkCommandBuffer cmd, const renderpass_op_callback_t& op) + { + const auto& active = g_current_renderpass[cmd]; + op(cmd, active.pass, active.fbo); + } } diff --git a/rpcs3/Emu/RSX/VK/VKRenderPass.h b/rpcs3/Emu/RSX/VK/VKRenderPass.h index a0d6d9e415..8f9750a42d 100644 --- a/rpcs3/Emu/RSX/VK/VKRenderPass.h +++ b/rpcs3/Emu/RSX/VK/VKRenderPass.h @@ -17,4 +17,7 @@ namespace vk void begin_renderpass(VkCommandBuffer cmd, VkRenderPass pass, VkFramebuffer target, const coordu& framebuffer_region); void end_renderpass(VkCommandBuffer cmd); bool is_renderpass_open(VkCommandBuffer cmd); + + using renderpass_op_callback_t = std::function; + void renderpass_op(VkCommandBuffer cmd, const renderpass_op_callback_t& op); }