diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.cpp b/rpcs3/Emu/RSX/VK/VKGSRender.cpp index bb993b221c..346909bf1b 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.cpp +++ b/rpcs3/Emu/RSX/VK/VKGSRender.cpp @@ -1743,6 +1743,8 @@ void VKGSRender::do_local_task(rsx::FIFO::state state) bool VKGSRender::load_program() { + const auto shadermode = g_cfg.video.shadermode.get(); + if (m_graphics_state & rsx::pipeline_state::invalidate_pipeline_bits) { get_current_fragment_program(fs_sampler_state); @@ -1752,10 +1754,25 @@ bool VKGSRender::load_program() m_graphics_state &= ~rsx::pipeline_state::invalidate_pipeline_bits; } + else if (!(m_graphics_state & rsx::pipeline_state::pipeline_config_dirty) && m_program) + { + if (!m_shader_interpreter.is_interpreter(m_program)) [[ likely ]] + { + return true; + } + + if (shadermode == shader_mode::interpreter_only) + { + m_program = m_shader_interpreter.get(m_pipeline_properties, current_fp_metadata); + return true; + } + } auto &vertex_program = current_vertex_program; auto &fragment_program = current_fragment_program; + m_cached_draw_state.prim = rsx::method_registers.current_draw_clause.primitive; + vk::pipeline_props properties{}; // Input assembly @@ -1915,7 +1932,6 @@ bool VKGSRender::load_program() } } - const auto shadermode = g_cfg.video.shadermode.get(); m_vertex_prog = nullptr; m_fragment_prog = nullptr; @@ -1966,6 +1982,7 @@ bool VKGSRender::load_program() } m_pipeline_properties = properties; + m_graphics_state &= ~rsx::pipeline_state::pipeline_config_dirty; return m_program != nullptr; } diff --git a/rpcs3/Emu/RSX/VK/VKGSRender.h b/rpcs3/Emu/RSX/VK/VKGSRender.h index 131e3cc2a8..3354e95fdb 100644 --- a/rpcs3/Emu/RSX/VK/VKGSRender.h +++ b/rpcs3/Emu/RSX/VK/VKGSRender.h @@ -94,7 +94,6 @@ private: struct { rsx::primitive_type prim = rsx::primitive_type::points; - bool primitive_restart = false; } m_cached_draw_state; public: diff --git a/rpcs3/Emu/RSX/rsx_methods.cpp b/rpcs3/Emu/RSX/rsx_methods.cpp index 9854675f73..4b40e0ef47 100644 --- a/rpcs3/Emu/RSX/rsx_methods.cpp +++ b/rpcs3/Emu/RSX/rsx_methods.cpp @@ -820,6 +820,7 @@ namespace rsx if (arg != method_registers.register_previous_value) { rsx->on_framebuffer_options_changed(reg); + rsx->m_graphics_state |= rsx::pipeline_config_dirty; } } @@ -2531,6 +2532,23 @@ namespace rsx state_signals[NV4097_SET_DEPTH_BOUNDS_MAX] = rsx::depth_bounds_state_dirty; state_signals[NV4097_SET_FRONT_FACE] = rsx::pipeline_config_dirty; state_signals[NV4097_SET_ZMIN_MAX_CONTROL] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_LOGIC_OP_ENABLE] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_LOGIC_OP] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_BLEND_ENABLE] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_BLEND_ENABLE_MRT] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_STENCIL_FUNC] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_BACK_STENCIL_FUNC] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_ANTI_ALIASING_CONTROL] = rsx::pipeline_config_dirty; + state_signals[NV4097_SET_RESTART_INDEX_ENABLE] = rsx::pipeline_config_dirty; + } + + // Sanity checks + for (size_t id = 0; id < methods.size(); ++id) + { + if (methods[id] && state_signals[id]) + { + rsx_log.error("FIXME: Method register 0x%x is registered as a method and signal. The signal will be ignored."); + } } } @@ -3534,7 +3552,6 @@ namespace rsx bind(NV4097_CLEAR_ZCULL_SURFACE, nv4097::clear_zcull); bind(NV4097_SET_DEPTH_TEST_ENABLE, nv4097::set_surface_options_dirty_bit); bind(NV4097_SET_DEPTH_FUNC, nv4097::set_surface_options_dirty_bit); - bind(NV4097_SET_STENCIL_TEST_ENABLE, nv4097::set_surface_options_dirty_bit); bind(NV4097_SET_DEPTH_MASK, nv4097::set_surface_options_dirty_bit); bind(NV4097_SET_COLOR_MASK, nv4097::set_surface_options_dirty_bit); bind(NV4097_SET_COLOR_MASK_MRT, nv4097::set_surface_options_dirty_bit);