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/Config.cpp
SPU2/Host/ConfigDebug.cpp SPU2/Host/ConfigDebug.cpp
SPU2/Host/ConfigSoundTouch.cpp SPU2/Host/ConfigSoundTouch.cpp
SPU2/Host/Dialogs.cpp
) )
list(APPEND pcsx2SPU2Headers list(APPEND pcsx2SPU2Headers
SPU2/Host/Config.h SPU2/Host/Config.h

View File

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

View File

@ -15,7 +15,7 @@
#pragma once #pragma once
#define NOMINMAX #include "PrecompiledHeader.h"
extern bool psxmode; extern bool psxmode;
@ -30,15 +30,6 @@ namespace soundtouch
class 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> template <typename T>
static __forceinline void Clampify(T& src, T min, T max) 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); 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) // Uncomment to enable debug keys on numpad (0 to 5)
//#define DEBUG_KEYS //#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 RecordStop();
extern void RecordWrite(const StereoOut16& sample); extern void RecordWrite(const StereoOut16& sample);
#ifndef PCSX2_CORE
extern s32 DspLoadLibrary(wchar_t* fileName, int modNum); extern s32 DspLoadLibrary(wchar_t* fileName, int modNum);
extern void DspCloseLibrary(); extern void DspCloseLibrary();
extern int DspProcess(s16* buffer, int samples); extern int DspProcess(s16* buffer, int samples);
extern void DspUpdate(); // to let the Dsp process window messages 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. :) m_wavrecord = nullptr; // not needed, but what the heck. :)
if (filename) 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 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; return false;
} }
} }

View File

@ -31,21 +31,19 @@
using namespace Threading; using namespace Threading;
std::recursive_mutex mtx_SPU2Status;
static int ConsoleSampleRate = 48000; static int ConsoleSampleRate = 48000;
int SampleRate = 48000; int SampleRate = 48000;
static double DeviceSampleRateMultiplier = 1.0; static double DeviceSampleRateMultiplier = 1.0;
static bool IsOpened = false;
static bool IsInitialized = false;
u32 lClocks = 0; u32 lClocks = 0;
#ifndef PCSX2_CORE #ifndef PCSX2_CORE
#include "gui/AppCoreThread.h" #include "gui/AppCoreThread.h"
static bool IsOpened = false;
std::recursive_mutex mtx_SPU2Status;
void SPU2configure() void SPU2configure()
{ {
ScopedCoreThreadPause paused_core(SystemsMask::System_SPU2); 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); SPU2InternalReset(isRunningPSXMode);
SPU2UpdateSampleRate(); SPU2UpdateSampleRate();
return 0;
} }
void SPU2SetDeviceSampleRateMultiplier(double multiplier) void SPU2SetDeviceSampleRateMultiplier(double multiplier)
@ -192,27 +189,9 @@ void SPU2SetDeviceSampleRateMultiplier(double multiplier)
SPU2UpdateSampleRate(); SPU2UpdateSampleRate();
} }
s32 SPU2init(bool KeepMode) bool SPU2init()
{ {
assert(regtable[0x400] == nullptr); pxAssert(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));
spu2regs = (s16*)malloc(0x010000); spu2regs = (s16*)malloc(0x010000);
_spu2mem = (s16*)malloc(0x200000); _spu2mem = (s16*)malloc(0x200000);
@ -225,10 +204,10 @@ s32 SPU2init(bool KeepMode)
pcm_cache_data = (PcmCacheEntry*)calloc(pcm_BlockCount, sizeof(PcmCacheEntry)); 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"); Console.Error("SPU2: Error allocating Memory");
return -1; return false;
} }
// Patch up a copy of regtable that directly maps "nullptrs" to SPU2 memory. // 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(); InitADSR();
return true;
return 0;
} }
#if defined(_MSC_VER) && !defined(PCSX2_CORE) #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; return TRUE;
} }
#endif #endif
uptr gsWindowHandle = 0;
s32 SPU2open() bool SPU2open(PS2Modes isRunningPSXMode)
{ {
#ifndef PCSX2_CORE
std::unique_lock lock(mtx_SPU2Status); std::unique_lock lock(mtx_SPU2Status);
if (IsOpened) 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 (IsDevBuild && VisualDebug())
{ {
if (debugDialogOpen == 0) if (debugDialogOpen == 0)
@ -321,9 +295,25 @@ s32 SPU2open()
#endif #endif
#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; lClocks = psxRegs.cycle;
SPU2InternalReset(isRunningPSXMode);
try try
{ {
SampleRate = static_cast<int>(std::round(static_cast<double>(ConsoleSampleRate) * DeviceSampleRateMultiplier)); SampleRate = static_cast<int>(std::round(static_cast<double>(ConsoleSampleRate) * DeviceSampleRateMultiplier));
@ -336,19 +326,22 @@ s32 SPU2open()
} }
catch (std::exception& ex) 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(); SPU2close();
return -1; return false;
} }
return 0;
return true;
} }
void SPU2close() void SPU2close()
{ {
#ifndef PCSX2_CORE
std::unique_lock lock(mtx_SPU2Status); std::unique_lock lock(mtx_SPU2Status);
if (!IsOpened) if (!IsOpened)
return; return;
IsOpened = false; IsOpened = false;
#endif
FileLog("[%10d] SPU2 Close\n", Cycles); FileLog("[%10d] SPU2 Close\n", Cycles);
@ -361,10 +354,6 @@ void SPU2close()
void SPU2shutdown() void SPU2shutdown()
{ {
if (!IsInitialized)
return;
IsInitialized = false;
ConLog("* SPU2: Shutting down.\n"); ConLog("* SPU2: Shutting down.\n");
SPU2close(); SPU2close();
@ -396,6 +385,11 @@ void SPU2shutdown()
#endif #endif
} }
bool SPU2IsRunningPSXMode()
{
return (ConsoleSampleRate == 44100);
}
void SPU2SetOutputPaused(bool paused) void SPU2SetOutputPaused(bool paused)
{ {
SndBuffer::SetPaused(paused); SndBuffer::SetPaused(paused);
@ -408,7 +402,9 @@ static bool lState[6];
void SPU2async(u32 cycles) void SPU2async(u32 cycles)
{ {
#ifndef PCSX2_CORE
DspUpdate(); DspUpdate();
#endif
TimeUpdate(psxRegs.cycle); TimeUpdate(psxRegs.cycle);

View File

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

View File

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

View File

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

View File

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

View File

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