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)
{
USING_SERIALIZATION_VERSION_COND(ar.is_writing(), cellAudioOut);
GET_OR_USE_SERIALIZATION_VERSION(ar.is_writing(), cellAudioOut);
for (auto& state : out)
{

View file

@ -145,7 +145,7 @@ void camera_context::save(utils::serial& ar)
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);
}

View file

@ -244,7 +244,7 @@ public:
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
, connected_controllers, update_started, camera_frame, memory_ptr, start_timestamp);

View file

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

View file

@ -48,7 +48,7 @@ void voice_manager::reset()
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);
}

View file

@ -30,6 +30,16 @@ namespace rsx
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)
{
m_internal_get += 4;
@ -806,13 +816,16 @@ namespace rsx
if (auto method = methods[reg])
{
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));
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;
std::span<const u32> get_current_arg_ptr() const;
u32 get_remaining_args_count() const { return m_remaining_commands; }
void restore_state(u32 cmd, u32 count);
void inc_get(bool wait);
void set_get(u32 get, u32 spin_cmd = 0);

View file

@ -438,7 +438,7 @@ namespace rsx
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);
@ -454,6 +454,27 @@ namespace rsx
ar(in_begin_end);
ar(display_buffers, display_buffers_count, current_display_buffer);
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)
@ -726,6 +747,8 @@ namespace rsx
performance_counters.state = FIFO_state::empty;
const u64 event_flags = unsent_gcm_events.exchange(0);
Emu.CallFromMainThread([]{ Emu.RunPPU(); });
// Wait for startup (TODO)
@ -751,11 +774,6 @@ namespace rsx
thread_ctrl::wait_for(1000);
}
if (is_stopped())
{
return;
}
performance_counters.state = FIFO_state::running;
fifo_ctrl = std::make_unique<::rsx::FIFO::FIFO_control>(this);
@ -765,12 +783,14 @@ namespace rsx
vblank_count = 0;
if (u64 event_flags = unsent_gcm_events.exchange(0))
if (restore_fifo_count)
{
if (!send_event(0, event_flags, 0))
{
return;
}
fifo_ctrl->restore_state(restore_fifo_cmd, restore_fifo_count);
}
if (!send_event(0, event_flags, 0))
{
return;
}
g_fxo->init<named_thread>("VBlank Thread", [this]()

View file

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

View file

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

View file

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

View file

@ -1168,10 +1168,11 @@ extern bool serialize(utils::serial& ar, T& obj);
using_##name##_serialization();\
}()
#define USING_SERIALIZATION_VERSION_COND(cond, name) [&]()\
#define GET_OR_USE_SERIALIZATION_VERSION(cond, name) [&]()\
{\
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) []()\