Savestates/RSX: Save NV406E semaphore waiting

This commit is contained in:
Eladash 2022-07-11 10:26:38 +03:00 committed by Ivan
parent 6211295155
commit ab27ee4cf4
12 changed files with 61 additions and 23 deletions

View file

@ -187,7 +187,7 @@ audio_out_configuration::audio_out_configuration(utils::serial& ar)
void audio_out_configuration::save(utils::serial& ar) void audio_out_configuration::save(utils::serial& ar)
{ {
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellAudioOut); GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellAudioOut);
for (auto& state : out) for (auto& state : out)
{ {

View file

@ -145,7 +145,7 @@ void camera_context::save(utils::serial& ar)
return; return;
} }
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellCamera); GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellCamera);
ar(notify_data_map, start_timestamp, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num); ar(notify_data_map, start_timestamp, read_mode, is_streaming, is_attached, is_open, info, attr, frame_num);
} }

View file

@ -244,7 +244,7 @@ public:
return; return;
} }
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellGem); GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellGem);
ar(attribute, vc_attribute, status_flags, enable_pitch_correction, inertial_counter, controllers ar(attribute, vc_attribute, status_flags, enable_pitch_correction, inertial_counter, controllers
, connected_controllers, update_started, camera_frame, memory_ptr, start_timestamp); , connected_controllers, update_started, camera_frame, memory_ptr, start_timestamp);

View file

@ -96,7 +96,7 @@ struct music_state
return; return;
} }
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellMusic); GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellMusic);
ar(userData); ar(userData);
} }

View file

@ -48,7 +48,7 @@ void voice_manager::reset()
void voice_manager::save(utils::serial& ar) void voice_manager::save(utils::serial& ar)
{ {
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellVoice); GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellVoice);
ar(id_ctr, port_source, ports, queue_keys, voice_service_started); ar(id_ctr, port_source, ports, queue_keys, voice_service_started);
} }

View file

@ -30,6 +30,16 @@ namespace rsx
m_ctrl->get.release(m_internal_get); m_ctrl->get.release(m_internal_get);
} }
void FIFO_control::restore_state(u32 cmd, u32 count)
{
m_cmd = cmd;
m_command_inc = ((m_cmd & RSX_METHOD_NON_INCREMENT_CMD_MASK) == RSX_METHOD_NON_INCREMENT_CMD) ? 0 : 4;
m_remaining_commands = count - 1;
m_internal_get = m_ctrl->get;
m_args_ptr = m_iotable->get_addr(m_internal_get);
m_command_reg = (m_cmd & 0xffff) + m_command_inc * (((m_cmd >> 18) - count) & 0x7ff);
}
void FIFO_control::inc_get(bool wait) void FIFO_control::inc_get(bool wait)
{ {
m_internal_get += 4; m_internal_get += 4;
@ -806,13 +816,16 @@ namespace rsx
if (auto method = methods[reg]) if (auto method = methods[reg])
{ {
method(this, reg, value); method(this, reg, value);
if (state & cpu_flag::again)
{
method_registers.decode(reg, method_registers.register_previous_value);
break;
}
} }
} }
while (fifo_ctrl->read_unsafe(command)); while (fifo_ctrl->read_unsafe(command));
if (cpu_flag::again - state) fifo_ctrl->sync_get();
{
fifo_ctrl->sync_get();
}
} }
} }

View file

@ -141,6 +141,7 @@ namespace rsx
void sync_get() const; void sync_get() const;
std::span<const u32> get_current_arg_ptr() const; std::span<const u32> get_current_arg_ptr() const;
u32 get_remaining_args_count() const { return m_remaining_commands; } u32 get_remaining_args_count() const { return m_remaining_commands; }
void restore_state(u32 cmd, u32 count);
void inc_get(bool wait); void inc_get(bool wait);
void set_get(u32 get, u32 spin_cmd = 0); void set_get(u32 get, u32 spin_cmd = 0);

View file

@ -438,7 +438,7 @@ namespace rsx
void thread::save(utils::serial& ar) void thread::save(utils::serial& ar)
{ {
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), rsx); [[maybe_unused]] const s32 version = GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), rsx);
ar(rsx::method_registers); ar(rsx::method_registers);
@ -454,6 +454,27 @@ namespace rsx
ar(in_begin_end); ar(in_begin_end);
ar(display_buffers, display_buffers_count, current_display_buffer); ar(display_buffers, display_buffers_count, current_display_buffer);
ar(unsent_gcm_events, rsx::method_registers.current_draw_clause); ar(unsent_gcm_events, rsx::method_registers.current_draw_clause);
if (ar.is_writing())
{
if (fifo_ctrl && state & cpu_flag::again)
{
ar(fifo_ctrl->get_remaining_args_count() + 1);
ar(fifo_ctrl->last_cmd());
}
else
{
ar(u32{0});
}
}
else if (version > 1)
{
if (u32 count = ar)
{
restore_fifo_count = count;
ar(restore_fifo_cmd);
}
}
} }
thread::thread(utils::serial* _ar) thread::thread(utils::serial* _ar)
@ -726,6 +747,8 @@ namespace rsx
performance_counters.state = FIFO_state::empty; performance_counters.state = FIFO_state::empty;
const u64 event_flags = unsent_gcm_events.exchange(0);
Emu.CallFromMainThread([]{ Emu.RunPPU(); }); Emu.CallFromMainThread([]{ Emu.RunPPU(); });
// Wait for startup (TODO) // Wait for startup (TODO)
@ -751,11 +774,6 @@ namespace rsx
thread_ctrl::wait_for(1000); thread_ctrl::wait_for(1000);
} }
if (is_stopped())
{
return;
}
performance_counters.state = FIFO_state::running; performance_counters.state = FIFO_state::running;
fifo_ctrl = std::make_unique<::rsx::FIFO::FIFO_control>(this); fifo_ctrl = std::make_unique<::rsx::FIFO::FIFO_control>(this);
@ -765,12 +783,14 @@ namespace rsx
vblank_count = 0; vblank_count = 0;
if (u64 event_flags = unsent_gcm_events.exchange(0)) if (restore_fifo_count)
{ {
if (!send_event(0, event_flags, 0)) fifo_ctrl->restore_state(restore_fifo_cmd, restore_fifo_count);
{ }
return;
} if (!send_event(0, event_flags, 0))
{
return;
} }
g_fxo->init<named_thread>("VBlank Thread", [this]() g_fxo->init<named_thread>("VBlank Thread", [this]()

View file

@ -478,6 +478,8 @@ namespace rsx
FIFO::flattening_helper m_flattener; FIFO::flattening_helper m_flattener;
u32 fifo_ret_addr = RSX_CALL_STACK_EMPTY; u32 fifo_ret_addr = RSX_CALL_STACK_EMPTY;
u32 saved_fifo_ret = RSX_CALL_STACK_EMPTY; u32 saved_fifo_ret = RSX_CALL_STACK_EMPTY;
u32 restore_fifo_cmd = 0;
u32 restore_fifo_count = 0;
// Occlusion query // Occlusion query
bool zcull_surface_active = false; bool zcull_surface_active = false;

View file

@ -115,6 +115,7 @@ namespace rsx
{ {
if (rsx->test_stopped()) if (rsx->test_stopped())
{ {
rsx->state += cpu_flag::again;
return; return;
} }

View file

@ -101,7 +101,7 @@ SERIALIZATION_VER(lv2_config, 9, 1)
namespace rsx namespace rsx
{ {
SERIALIZATION_VER(rsx, 10, 1) SERIALIZATION_VER(rsx, 10, 1, 2)
} }
namespace np namespace np

View file

@ -1168,10 +1168,11 @@ extern bool serialize(utils::serial& ar, T& obj);
using_##name##_serialization();\ using_##name##_serialization();\
}() }()
#define USING_SERIALIZATION_VERSION_COND(cond, name) [&]()\ #define GET_OR_USE_SERIALIZATION_VERSION(cond, name) [&]()\
{\ {\
extern void using_##name##_serialization();\ extern void using_##name##_serialization();\
if (static_cast<bool>(cond)) using_##name##_serialization();\ extern s32 get_##name##_serialization_version();\
return (static_cast<bool>(cond) ? (using_##name##_serialization(), 0) : get_##name##_serialization_version());\
}() }()
#define GET_SERIALIZATION_VERSION(name) []()\ #define GET_SERIALIZATION_VERSION(name) []()\