VMManager: Better separate shutdown and close for SPU2 and GS

This commit is contained in:
Connor McLaughlin 2022-12-04 18:56:51 +10:00 committed by refractionpcsx2
parent dfcf9fa6aa
commit ce412686b9
12 changed files with 74 additions and 123 deletions

View File

@ -819,7 +819,6 @@ if(PCSX2_CORE)
SPU2/Host/Config.cpp
SPU2/Host/ConfigDebug.cpp
SPU2/Host/ConfigSoundTouch.cpp
SPU2/Host/Dialogs.cpp
)
list(APPEND pcsx2SPU2Headers
SPU2/Host/Config.h

View File

@ -131,6 +131,9 @@ void GSshutdown()
s_hr = E_FAIL;
}
#endif
// ensure all screenshots have been saved
GSJoinSnapshotThreads();
}
void GSclose()
@ -150,9 +153,6 @@ void GSclose()
g_host_display->SetGPUTimingEnabled(false);
Host::ReleaseHostDisplay(true);
// ensure all screenshots have been saved
GSJoinSnapshotThreads();
}
static RenderAPI GetAPIForRenderer(GSRendererType renderer)

View File

@ -15,7 +15,7 @@
#pragma once
#define NOMINMAX
#include "PrecompiledHeader.h"
extern bool psxmode;
@ -30,15 +30,6 @@ namespace soundtouch
class SoundTouch;
}
#include "PrecompiledHeader.h"
//////////////////////////////////////////////////////////////////////////
// Override Win32 min/max macros with the STL's type safe and macro
// free varieties (much safer!)
#undef min
#undef max
template <typename T>
static __forceinline void Clampify(T& src, T min, T max)
{
@ -51,8 +42,6 @@ static __forceinline T GetClamped(T src, T min, T max)
return std::min(std::max(src, min), max);
}
extern void SysMessage(const char* fmt, ...);
extern void SysMessage(const wchar_t* fmt, ...);
// Uncomment to enable debug keys on numpad (0 to 5)
//#define DEBUG_KEYS

View File

@ -1,38 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2020 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
// To be continued...
#include "PrecompiledHeader.h"
#include "Dialogs.h"
#include <cstring>
#include <cstdarg>
void SysMessage(const char* fmt, ...)
{
va_list list;
va_start(list, fmt);
vfprintf(stderr, fmt, list);
va_end(list);
}
void DspUpdate()
{
}
s32 DspLoadLibrary(wchar_t* fileName, int modnum)
{
return 0;
}

View File

@ -676,7 +676,9 @@ extern bool RecordStart(const std::string* filename);
extern void RecordStop();
extern void RecordWrite(const StereoOut16& sample);
#ifndef PCSX2_CORE
extern s32 DspLoadLibrary(wchar_t* fileName, int modNum);
extern void DspCloseLibrary();
extern int DspProcess(s16* buffer, int samples);
extern void DspUpdate(); // to let the Dsp process window messages
#endif

View File

@ -134,9 +134,9 @@ bool RecordStart(const std::string* filename)
{
m_wavrecord = nullptr; // not needed, but what the heck. :)
if (filename)
SysMessage("SPU2 couldn't open file for recording: %s.\nWavfile capture disabled.", filename->c_str());
Console.Error("SPU2 couldn't open file for recording: %s.\nWavfile capture disabled.", filename->c_str());
else
SysMessage("SPU2 couldn't open file for recording: audio_recording.wav.\nWavfile capture disabled.");
Console.Error("SPU2 couldn't open file for recording: audio_recording.wav.\nWavfile capture disabled.");
return false;
}
}

View File

@ -31,21 +31,19 @@
using namespace Threading;
std::recursive_mutex mtx_SPU2Status;
static int ConsoleSampleRate = 48000;
int SampleRate = 48000;
static double DeviceSampleRateMultiplier = 1.0;
static bool IsOpened = false;
static bool IsInitialized = false;
u32 lClocks = 0;
#ifndef PCSX2_CORE
#include "gui/AppCoreThread.h"
static bool IsOpened = false;
std::recursive_mutex mtx_SPU2Status;
void SPU2configure()
{
ScopedCoreThreadPause paused_core(SystemsMask::System_SPU2);
@ -176,11 +174,10 @@ static void SPU2InternalReset(PS2Modes isRunningPSXMode)
}
}
s32 SPU2reset(PS2Modes isRunningPSXMode)
void SPU2reset(PS2Modes isRunningPSXMode)
{
SPU2InternalReset(isRunningPSXMode);
SPU2UpdateSampleRate();
return 0;
}
void SPU2SetDeviceSampleRateMultiplier(double multiplier)
@ -192,27 +189,9 @@ void SPU2SetDeviceSampleRateMultiplier(double multiplier)
SPU2UpdateSampleRate();
}
s32 SPU2init(bool KeepMode)
bool SPU2init()
{
assert(regtable[0x400] == nullptr);
if (IsInitialized)
return 0;
IsInitialized = true;
ReadSettings();
#ifdef SPU2_LOG
if (AccessLog())
{
spu2Log = OpenLog(AccessLogFileName.c_str());
setvbuf(spu2Log, nullptr, _IONBF, 0);
FileLog("SPU2init\n");
}
#endif
srand((unsigned)time(nullptr));
pxAssert(regtable[0x400] == nullptr);
spu2regs = (s16*)malloc(0x010000);
_spu2mem = (s16*)malloc(0x200000);
@ -225,10 +204,10 @@ s32 SPU2init(bool KeepMode)
pcm_cache_data = (PcmCacheEntry*)calloc(pcm_BlockCount, sizeof(PcmCacheEntry));
if ((spu2regs == nullptr) || (_spu2mem == nullptr) || (pcm_cache_data == nullptr))
if (!spu2regs || !_spu2mem || !pcm_cache_data)
{
SysMessage("SPU2: Error allocating Memory\n");
return -1;
Console.Error("SPU2: Error allocating Memory");
return false;
}
// Patch up a copy of regtable that directly maps "nullptrs" to SPU2 memory.
@ -244,12 +223,8 @@ s32 SPU2init(bool KeepMode)
}
}
SPU2InternalReset((ConsoleSampleRate == 44100 && KeepMode) ? PS2Modes::PSX : PS2Modes::PS2);
DMALogOpen();
InitADSR();
return 0;
return true;
}
#if defined(_MSC_VER) && !defined(PCSX2_CORE)
@ -292,18 +267,17 @@ static INT_PTR CALLBACK DebugProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lP
return TRUE;
}
#endif
uptr gsWindowHandle = 0;
s32 SPU2open()
bool SPU2open(PS2Modes isRunningPSXMode)
{
#ifndef PCSX2_CORE
std::unique_lock lock(mtx_SPU2Status);
if (IsOpened)
return 0;
return true;
FileLog("[%10d] SPU2 Open\n", Cycles);
#if defined(_MSC_VER) && defined(PCSX2_DEVBUILD) // Define may not be needed but not tested yet. Better make sure.
IsOpened = true;
#if defined(_MSC_VER) && !defined(PCSX2_CORE)
#ifdef PCSX2_DEVBUILD // Define may not be needed but not tested yet. Better make sure.
if (IsDevBuild && VisualDebug())
{
if (debugDialogOpen == 0)
@ -321,9 +295,25 @@ s32 SPU2open()
#endif
#endif
IsOpened = true;
ReadSettings();
#ifdef SPU2_LOG
if (AccessLog())
{
spu2Log = OpenLog(AccessLogFileName.c_str());
setvbuf(spu2Log, nullptr, _IONBF, 0);
FileLog("SPU2init\n");
}
#endif
DMALogOpen();
FileLog("[%10d] SPU2 Open\n", Cycles);
lClocks = psxRegs.cycle;
SPU2InternalReset(isRunningPSXMode);
try
{
SampleRate = static_cast<int>(std::round(static_cast<double>(ConsoleSampleRate) * DeviceSampleRateMultiplier));
@ -336,19 +326,22 @@ s32 SPU2open()
}
catch (std::exception& ex)
{
fprintf(stderr, "SPU2 Error: Could not initialize device, or something.\nReason: %s", ex.what());
Console.Error("SPU2 Error: Could not initialize device, or something.\nReason: %s", ex.what());
SPU2close();
return -1;
return false;
}
return 0;
return true;
}
void SPU2close()
{
#ifndef PCSX2_CORE
std::unique_lock lock(mtx_SPU2Status);
if (!IsOpened)
return;
IsOpened = false;
#endif
FileLog("[%10d] SPU2 Close\n", Cycles);
@ -361,10 +354,6 @@ void SPU2close()
void SPU2shutdown()
{
if (!IsInitialized)
return;
IsInitialized = false;
ConLog("* SPU2: Shutting down.\n");
SPU2close();
@ -396,6 +385,11 @@ void SPU2shutdown()
#endif
}
bool SPU2IsRunningPSXMode()
{
return (ConsoleSampleRate == 44100);
}
void SPU2SetOutputPaused(bool paused)
{
SndBuffer::SetPaused(paused);
@ -408,7 +402,9 @@ static bool lState[6];
void SPU2async(u32 cycles)
{
#ifndef PCSX2_CORE
DspUpdate();
#endif
TimeUpdate(psxRegs.cycle);

View File

@ -19,7 +19,9 @@
#include "IopCounters.h"
#include <mutex>
#ifndef PCSX2_CORE
extern std::recursive_mutex mtx_SPU2Status;
#endif
enum class PS2Modes
{
@ -27,11 +29,12 @@ enum class PS2Modes
PSX,
};
s32 SPU2init(bool KeepMode);
s32 SPU2reset(PS2Modes isRunningPSXMode);
s32 SPU2open();
bool SPU2init();
void SPU2reset(PS2Modes isRunningPSXMode = PS2Modes::PS2);
bool SPU2open(PS2Modes isRunningPSXMode = PS2Modes::PS2);
void SPU2close();
void SPU2shutdown();
bool SPU2IsRunningPSXMode();
void SPU2SetOutputPaused(bool paused);
void SPU2SetDeviceSampleRateMultiplier(double multiplier);
void SPU2write(u32 mem, u16 value);

View File

@ -267,11 +267,20 @@ bool VMManager::Internal::InitializeGlobals()
return false;
}
if (!SPU2init())
{
Host::ReportErrorAsync("Error", "Failed to initialize SPU2 (SPU2init()).");
return false;
}
return true;
}
void VMManager::Internal::ReleaseGlobals()
{
SPU2shutdown();
GSshutdown();
#ifdef _WIN32
CoUninitialize();
#endif
@ -954,16 +963,12 @@ bool VMManager::Initialize(VMBootParameters boot_params)
};
Console.WriteLn("Opening SPU2...");
if (SPU2init(false) != 0 || SPU2open() != 0)
if (!SPU2open())
{
Host::ReportErrorAsync("Startup Error", "Failed to initialize SPU2.");
SPU2shutdown();
return false;
}
ScopedGuard close_spu2 = []() {
SPU2close();
SPU2shutdown();
};
ScopedGuard close_spu2(&SPU2close);
Console.WriteLn("Opening PAD...");
if (PADinit() != 0 || PADopen(g_host_display->GetWindowInfo()) != 0)
@ -1136,10 +1141,8 @@ void VMManager::Shutdown(bool save_resume_state)
}
USBshutdown();
SPU2shutdown();
PADshutdown();
DEV9shutdown();
GSshutdown();
s_state.store(VMState::Shutdown, std::memory_order_release);
Host::OnVMDestroyed();
@ -1715,9 +1718,10 @@ void VMManager::CheckForSPU2ConfigChanges(const Pcsx2Config& old_config)
return;
}
const bool psxmode = SPU2IsRunningPSXMode();
SPU2close();
SPU2shutdown();
if (SPU2init(true) != 0 || SPU2open() != 0)
if (!SPU2open(psxmode ? PS2Modes::PSX : PS2Modes::PS2))
{
Console.Error("(CheckForSPU2ConfigChanges) Failed to reopen SPU2, we'll probably crash :(");
return;

View File

@ -111,7 +111,7 @@ void SysCoreThread::OnSuspendInThread()
void SysCoreThread::Start()
{
SPU2init(false);
SPU2init();
PADinit();
DEV9init();
USBinit();

View File

@ -248,7 +248,6 @@
<ClCompile Include="SPU2\Host\Config.cpp" />
<ClCompile Include="SPU2\Host\ConfigDebug.cpp" />
<ClCompile Include="SPU2\Host\ConfigSoundTouch.cpp" />
<ClCompile Include="SPU2\Host\Dialogs.cpp" />
<ClCompile Include="SPU2\RegLog.cpp" />
<ClCompile Include="SPU2\SndOut_Cubeb.cpp" />
<ClCompile Include="SPU2\wavedump_wav.cpp" />

View File

@ -1214,9 +1214,6 @@
<ClCompile Include="SPU2\Host\ConfigSoundTouch.cpp">
<Filter>System\Ps2\SPU2</Filter>
</ClCompile>
<ClCompile Include="SPU2\Host\Dialogs.cpp">
<Filter>System\Ps2\SPU2</Filter>
</ClCompile>
<ClCompile Include="SPU2\Host\Config.cpp">
<Filter>System\Ps2\SPU2</Filter>
</ClCompile>