Add a central variable g_want_determinism which controls whether to try to make things deterministic.

It now affects the GPU determinism mode as well as some miscellaneous
things that were calling IsNetPlayRunning.  Probably incomplete.

Notably, this can change while paused, if the user starts recording a
movie.  The movie code appears to have been missing locking between
setting g_playMode and doing other things, which probably had a small
chance of causing crashes or even desynced movies; fix that with
PauseAndLock.

The next commit will add a hidden config variable to override GPU
determinism mode.
This commit is contained in:
comex committed 2014-09-28 21:34:31 -04:00
1 parent 65af90669b
commit 3a2048ea57
10 files changed
+95 -8

No files matched your search

+31
View File
@@ -48,6 +48,7 @@
#include "Core/HW/VideoInterface.h"
#include "Core/HW/Wiimote.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device_usb.h"
#include "Core/IPC_HLE/WII_Socket.h"
#include "Core/PowerPC/PowerPC.h"
#ifdef USE_GDBSTUB
@@ -65,6 +66,8 @@ bool g_aspect_wide;
namespace Core
{
bool g_want_determinism;
// Declarations and definitions
static Common::Timer s_timer;
static volatile u32 s_drawn_frame = 0;
@@ -177,6 +180,8 @@ bool Init()
s_emu_thread.join();
}
Core::UpdateWantDeterminism(/*initial*/ true);
INFO_LOG(OSREPORT, "Starting core = %s mode",
_CoreParameter.bWii ? "Wii" : "GameCube");
INFO_LOG(OSREPORT, "CPU Thread separate = %s",
@@ -564,6 +569,9 @@ void RequestRefreshInfo()
bool PauseAndLock(bool doLock, bool unpauseOnUnlock)
{
if (!IsRunning())
return true;
// let's support recursive locking to simplify things on the caller's side,
// and let's do it at this outer level in case the individual systems don't support it.
if (doLock ? s_pause_and_lock_depth++ : --s_pause_and_lock_depth)
@@ -702,4 +710,27 @@ void SetOnStoppedCallback(StoppedCallbackFunc callback)
s_on_stopped_callback = callback;
}
void UpdateWantDeterminism(bool initial)
{
// For now, this value is not itself configurable. Instead, individual
// settings that depend on it, such as GPU determinism mode. should have
// override options for testing,
bool new_want_determinism =
Movie::IsPlayingInput() ||
Movie::IsRecordingInput() ||
NetPlay::IsNetPlayRunning();
if (new_want_determinism != g_want_determinism || initial)
{
WARN_LOG(COMMON, "Want determinism <- %s", new_want_determinism ? "true" : "false");
bool was_unpaused = Core::PauseAndLock(true);
g_want_determinism = new_want_determinism;
WiiSockMan::GetInstance().UpdateWantDeterminism(new_want_determinism);
g_video_backend->UpdateWantDeterminism(new_want_determinism);
Core::PauseAndLock(false, was_unpaused);
}
}
} // Core
+5
View File
@@ -23,6 +23,8 @@ extern bool g_aspect_wide;
namespace Core
{
extern bool g_want_determinism;
bool GetIsFramelimiterTempDisabled();
void SetIsFramelimiterTempDisabled(bool disable);
@@ -79,4 +81,7 @@ bool PauseAndLock(bool doLock, bool unpauseOnUnlock=true);
typedef void(*StoppedCallbackFunc)(void);
void SetOnStoppedCallback(StoppedCallbackFunc callback);
// Run on the GUI thread when the factors change.
void UpdateWantDeterminism(bool initial = false);
} // namespace
@@ -331,7 +331,7 @@ bool Wiimote::Step()
m_rumble->controls[0]->control_ref->State(m_rumble_on);
// when a movie is active, this button status update is disabled (moved), because movies only record data reports.
if (!(Movie::IsMovieActive()) || NetPlay::IsNetPlayRunning())
if (!Core::g_want_determinism)
{
UpdateButtonsStatus();
}
@@ -385,7 +385,7 @@ void Wiimote::UpdateButtonsStatus()
void Wiimote::GetCoreData(u8* const data)
{
// when a movie is active, the button update happens here instead of Wiimote::Step, to avoid potential desync issues.
if (Movie::IsMovieActive() || NetPlay::IsNetPlayRunning())
if (Core::g_want_determinism)
{
UpdateButtonsStatus();
}
+9 -5
View File
@@ -4,8 +4,7 @@
#include <algorithm>
#include "Core/Movie.h"
#include "Core/NetPlayProto.h"
#include "Core/Core.h"
#include "Core/IPC_HLE/WII_IPC_HLE.h"
#include "Core/IPC_HLE/WII_IPC_HLE_Device.h"
#include "Core/IPC_HLE/WII_Socket.h" // No Wii socket support while using NetPlay or TAS
@@ -559,9 +558,7 @@ void WiiSockMan::AddSocket(s32 fd)
s32 WiiSockMan::NewSocket(s32 af, s32 type, s32 protocol)
{
if (NetPlay::IsNetPlayRunning() ||
Movie::IsRecordingInput() ||
Movie::IsPlayingInput())
if (Core::g_want_determinism)
{
return SO_ENOMEM;
}
@@ -664,5 +661,12 @@ void WiiSockMan::Convert(sockaddr_in const & from, WiiSockAddrIn& to, s32 addrle
to.len = addrlen;
}
void WiiSockMan::UpdateWantDeterminism(bool want)
{
// If we switched into movie recording, kill existing sockets.
if (want)
Clean();
}
#undef ERRORCODE
#undef EITHER
+2
View File
@@ -242,6 +242,8 @@ public:
}
}
void UpdateWantDeterminism(bool want);
private:
WiiSockMan() = default;
+9
View File
@@ -437,6 +437,8 @@ bool BeginRecordingInput(int controllers)
if (s_playMode != MODE_NONE || controllers == 0)
return false;
bool was_unpaused = Core::PauseAndLock(true);
s_numPads = controllers;
g_currentFrame = g_totalFrames = 0;
g_currentLagCount = s_totalLagCount = 0;
@@ -487,6 +489,10 @@ bool BeginRecordingInput(int controllers)
s_currentByte = s_totalBytes = 0;
Core::UpdateWantDeterminism();
Core::PauseAndLock(false, was_unpaused);
Core::DisplayMessage("Starting movie recording", 2000);
return true;
}
@@ -764,6 +770,8 @@ bool PlayInput(const std::string& filename)
s_playMode = MODE_PLAYING;
Core::UpdateWantDeterminism();
s_totalBytes = g_recordfd.GetSize() - 256;
EnsureTmpInputSize((size_t)s_totalBytes);
g_recordfd.ReadArray(tmpInput, (size_t)s_totalBytes);
@@ -1097,6 +1105,7 @@ void EndPlayInput(bool cont)
s_rerecords = 0;
s_currentByte = 0;
s_playMode = MODE_NONE;
Core::UpdateWantDeterminism();
Core::DisplayMessage("Movie End.", 2000);
s_bRecordingFromSaveState = false;
// we don't clear these things because otherwise we can't resume playback if we load a movie state later