Merge pull request #11634 from AdmiralCurtiss/dsp-class

HW/DSP: Refactor to class.
This commit is contained in:
Mai
2023-03-09 20:06:53 -05:00
committed by GitHub
19 changed files with 406 additions and 398 deletions
+3 -2
View File
@@ -568,7 +568,8 @@ static void EmuThread(std::unique_ptr<BootParameters> boot, WindowSystemInfo wsi
else
Config::SetBaseOrCurrent(Config::MAIN_DSP_THREAD, cpu_info.num_cores > 2);
if (!DSP::GetDSPEmulator()->Initialize(core_parameter.bWii, Config::Get(Config::MAIN_DSP_THREAD)))
if (!system.GetDSP().GetDSPEmulator()->Initialize(core_parameter.bWii,
Config::Get(Config::MAIN_DSP_THREAD)))
{
PanicAlertFmt("Failed to initialize DSP emulation!");
return;
@@ -785,7 +786,7 @@ static bool PauseAndLock(Core::System& system, bool do_lock, bool unpause_on_unl
ExpansionInterface::PauseAndLock(do_lock, false);
// audio has to come after CPU, because CPU thread can wait for audio thread (m_throttle).
DSP::GetDSPEmulator()->PauseAndLock(do_lock, false);
system.GetDSP().GetDSPEmulator()->PauseAndLock(do_lock, false);
// video has to come after CPU, because CPU thread can wait for video thread
// (s_efbAccessRequested).
@@ -325,8 +325,11 @@ u32 PPCDebugInterface::ReadExtraMemory(const Core::CPUThreadGuard& guard, int me
case 0:
return PowerPC::HostRead_U32(guard, address);
case 1:
return (DSP::ReadARAM(address) << 24) | (DSP::ReadARAM(address + 1) << 16) |
(DSP::ReadARAM(address + 2) << 8) | (DSP::ReadARAM(address + 3));
{
auto& dsp = Core::System::GetInstance().GetDSP();
return (dsp.ReadARAM(address) << 24) | (dsp.ReadARAM(address + 1) << 16) |
(dsp.ReadARAM(address + 2) << 8) | (dsp.ReadARAM(address + 3));
}
default:
return 0;
}
+7 -4
View File
@@ -212,19 +212,22 @@ struct AuxiliaryAddressSpaceAccessors : Accessors
}
u8 ReadU8(const Core::CPUThreadGuard& guard, u32 address) const override
{
const u8* base = DSP::GetARAMPtr();
const u8* base = Core::System::GetInstance().GetDSP().GetARAMPtr();
return base[address];
}
void WriteU8(const Core::CPUThreadGuard& guard, u32 address, u8 value) override
{
u8* base = DSP::GetARAMPtr();
u8* base = Core::System::GetInstance().GetDSP().GetARAMPtr();
base[address] = value;
}
iterator begin() const override { return DSP::GetARAMPtr(); }
iterator begin() const override { return Core::System::GetInstance().GetDSP().GetARAMPtr(); }
iterator end() const override { return DSP::GetARAMPtr() + GetSize(); }
iterator end() const override
{
return Core::System::GetInstance().GetDSP().GetARAMPtr() + GetSize();
}
std::optional<u32> Search(const Core::CPUThreadGuard& guard, u32 haystack_offset,
const u8* needle_start, std::size_t needle_size,
File diff suppressed because it is too large Load Diff
+121 -32
View File
@@ -9,6 +9,14 @@
class PointerWrap;
class DSPEmulator;
namespace Core
{
class System;
}
namespace CoreTiming
{
struct EventType;
}
namespace MMIO
{
class Mapping;
@@ -16,23 +24,6 @@ class Mapping;
namespace DSP
{
class DSPState
{
public:
DSPState();
DSPState(const DSPState&) = delete;
DSPState(DSPState&&) = delete;
DSPState& operator=(const DSPState&) = delete;
DSPState& operator=(DSPState&&) = delete;
~DSPState();
struct Data;
Data& GetData() { return *m_data; }
private:
std::unique_ptr<Data> m_data;
};
enum DSPInterruptType
{
INT_DSP = 0x80,
@@ -77,27 +68,125 @@ union UDSPControl
UDSPControl(u16 hex = 0) : Hex(hex) {}
};
void Init(bool hle);
void Reinit(bool hle);
void Shutdown();
class DSPManager
{
public:
explicit DSPManager(Core::System& system);
DSPManager(const DSPManager&) = delete;
DSPManager(DSPManager&&) = delete;
DSPManager& operator=(const DSPManager&) = delete;
DSPManager& operator=(DSPManager&&) = delete;
~DSPManager();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void Init(bool hle);
void Reinit(bool hle);
void Shutdown();
DSPEmulator* GetDSPEmulator();
void RegisterMMIO(MMIO::Mapping* mmio, u32 base);
void DoState(PointerWrap& p);
DSPEmulator* GetDSPEmulator();
// TODO: Maybe rethink this? The timing is unpredictable.
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, int cycles_into_future = 0);
void DoState(PointerWrap& p);
// Audio/DSP Helper
u8 ReadARAM(u32 address);
void WriteARAM(u8 value, u32 address);
// TODO: Maybe rethink this? The timing is unpredictable.
void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type, int cycles_into_future = 0);
// Debugger Helper
u8* GetARAMPtr();
// Audio/DSP Helper
u8 ReadARAM(u32 address) const;
void WriteARAM(u8 value, u32 address);
void UpdateAudioDMA();
void UpdateDSPSlice(int cycles);
// Debugger Helper
u8* GetARAMPtr() const;
void UpdateAudioDMA();
void UpdateDSPSlice(int cycles);
private:
void GenerateDSPInterrupt(u64 DSPIntType, s64 cyclesLate);
static void GlobalGenerateDSPInterrupt(Core::System& system, u64 DSPIntType, s64 cyclesLate);
void CompleteARAM(u64 userdata, s64 cyclesLate);
static void GlobalCompleteARAM(Core::System& system, u64 userdata, s64 cyclesLate);
void UpdateInterrupts();
void Do_ARAM_DMA();
// UARAMCount
union UARAMCount
{
u32 Hex = 0;
struct
{
u32 count : 31;
u32 dir : 1; // 0: MRAM -> ARAM 1: ARAM -> MRAM
};
};
// Blocks are 32 bytes.
union UAudioDMAControl
{
u16 Hex = 0;
struct
{
u16 NumBlocks : 15;
u16 Enable : 1;
};
};
// AudioDMA
struct AudioDMA
{
u32 current_source_address = 0;
u16 remaining_blocks_count = 0;
u32 SourceAddress = 0;
UAudioDMAControl AudioDMAControl;
};
// ARAM_DMA
struct ARAM_DMA
{
u32 MMAddr = 0;
u32 ARAddr = 0;
UARAMCount Cnt;
};
// So we may abstract GC/Wii differences a little
struct ARAMInfo
{
bool wii_mode = false; // Wii EXRAM is managed in Memory:: so we need to skip statesaving, etc
u32 size = ARAM_SIZE;
u32 mask = ARAM_MASK;
u8* ptr = nullptr; // aka audio ram, auxiliary ram, MEM2, EXRAM, etc...
};
union ARAM_Info
{
u16 Hex = 0;
struct
{
u16 size : 6;
u16 unk : 1;
u16 : 9;
};
};
ARAMInfo m_aram;
AudioDMA m_audio_dma;
ARAM_DMA m_aram_dma;
UDSPControl m_dsp_control;
ARAM_Info m_aram_info;
// Contains bitfields for some stuff we don't care about (and nothing ever reads):
// CAS latency/burst length/addressing mode/write mode
// We care about the LSB tho. It indicates that the ARAM controller has finished initializing
u16 m_aram_mode = 0;
u16 m_aram_refresh = 0;
int m_dsp_slice = 0;
std::unique_ptr<DSPEmulator> m_dsp_emulator;
bool m_is_lle = false;
CoreTiming::EventType* m_event_type_generate_dsp_interrupt = nullptr;
CoreTiming::EventType* m_event_type_complete_aram = nullptr;
Core::System& m_system;
};
} // namespace DSP
+4 -2
View File
@@ -8,6 +8,7 @@
#include "Common/Logging/Log.h"
#include "Common/MsgHandler.h"
#include "Core/HW/DSP.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -25,7 +26,8 @@ void CMailHandler::PushMail(u32 mail, bool interrupt, int cycles_into_future)
{
if (m_pending_mails.empty())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP, cycles_into_future);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP,
cycles_into_future);
}
else
{
@@ -58,7 +60,7 @@ u16 CMailHandler::ReadDSPMailboxLow()
if (generate_interrupt)
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
}
// Clear the top bit of the high mail word after the mail has been read.
+10 -3
View File
@@ -16,6 +16,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -94,7 +95,7 @@ void AESndUCode::Update()
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
if (m_mail_handler.HasPending())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
}
@@ -246,8 +247,14 @@ protected:
SetPredScale(GetPredScale());
}
u8 ReadMemory(u32 address) override { return ReadARAM(address); }
void WriteMemory(u32 address, u8 value) override { WriteARAM(value, address); }
u8 ReadMemory(u32 address) override
{
return Core::System::GetInstance().GetDSP().ReadARAM(address);
}
void WriteMemory(u32 address, u8 value) override
{
Core::System::GetInstance().GetDSP().WriteARAM(value, address);
}
};
static std::unique_ptr<Accelerator> s_accelerator = std::make_unique<AESndAccelerator>();
+2 -1
View File
@@ -15,6 +15,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -79,7 +80,7 @@ void ASndUCode::Update()
// This is dubious in general, since we set the interrupt parameter on m_mail_handler.PushMail
if (m_mail_handler.HasPending())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
}
+8 -2
View File
@@ -187,8 +187,14 @@ protected:
}
}
u8 ReadMemory(u32 address) override { return ReadARAM(address); }
void WriteMemory(u32 address, u8 value) override { WriteARAM(value, address); }
u8 ReadMemory(u32 address) override
{
return Core::System::GetInstance().GetDSP().ReadARAM(address);
}
void WriteMemory(u32 address, u8 value) override
{
Core::System::GetInstance().GetDSP().WriteARAM(value, address);
}
};
static std::unique_ptr<Accelerator> s_accelerator = std::make_unique<HLEAccelerator>();
+2 -1
View File
@@ -9,6 +9,7 @@
#include "Core/HW/DSP.h"
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -27,7 +28,7 @@ void CARDUCode::Update()
// check if we have something to send
if (m_mail_handler.HasPending())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
}
+2 -1
View File
@@ -11,6 +11,7 @@
#include "Core/HW/DSPHLE/DSPHLE.h"
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -84,7 +85,7 @@ void GBAUCode::Update()
// check if we have something to send
if (m_mail_handler.HasPending())
{
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
}
+3 -2
View File
@@ -16,6 +16,7 @@
#include "Core/HW/DSPHLE/MailHandler.h"
#include "Core/HW/DSPHLE/UCodes/GBA.h"
#include "Core/HW/DSPHLE/UCodes/UCodes.h"
#include "Core/System.h"
namespace DSP::HLE
{
@@ -367,7 +368,7 @@ void ZeldaUCode::HandleMailLight(u32 mail)
m_sync_max_voice_id = 0xFFFFFFFF;
m_sync_voice_skip_flags.fill(0xFFFF);
RenderAudio();
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
break;
case MailState::HALTED:
@@ -1542,7 +1543,7 @@ void* ZeldaAudioRenderer::GetARAMPtr() const
if (m_aram_base_addr)
return HLEMemory_Get_Pointer(m_aram_base_addr);
else
return DSP::GetARAMPtr();
return Core::System::GetInstance().GetDSP().GetARAMPtr();
}
template <typename T>
+3 -3
View File
@@ -30,12 +30,12 @@ namespace DSP::Host
{
u8 ReadHostMemory(u32 addr)
{
return DSP::ReadARAM(addr);
return Core::System::GetInstance().GetDSP().ReadARAM(addr);
}
void WriteHostMemory(u8 value, u32 addr)
{
DSP::WriteARAM(value, addr);
Core::System::GetInstance().GetDSP().WriteARAM(value, addr);
}
void DMAToDSP(u16* dst, u32 addr, u32 size)
@@ -70,7 +70,7 @@ bool IsWiiHost()
void InterruptRequest()
{
// Fire an interrupt on the PPC ASAP.
DSP::GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
Core::System::GetInstance().GetDSP().GenerateDSPInterruptFromDSPEmu(DSP::INT_DSP);
}
void CodeLoaded(DSPCore& dsp, u32 addr, size_t size)
+3 -3
View File
@@ -49,7 +49,7 @@ void Init(const Sram* override_sram)
system.GetMemory().Init(); // Needs to be initialized before AddressSpace
AddressSpace::Init();
MemoryInterface::Init();
DSP::Init(Config::Get(Config::MAIN_DSP_HLE));
system.GetDSP().Init(Config::Get(Config::MAIN_DSP_HLE));
DVDInterface::Init();
system.GetGPFifo().Init();
system.GetCPU().Init(Config::Get(Config::MAIN_CPU_CORE));
@@ -73,7 +73,7 @@ void Shutdown()
SystemTimers::Shutdown();
system.GetCPU().Shutdown();
DVDInterface::Shutdown();
DSP::Shutdown();
system.GetDSP().Shutdown();
MemoryInterface::Shutdown();
AddressSpace::Shutdown();
system.GetMemory().Shutdown();
@@ -99,7 +99,7 @@ void DoState(PointerWrap& p)
p.DoMarker("SerialInterface");
system.GetProcessorInterface().DoState(p);
p.DoMarker("ProcessorInterface");
DSP::DoState(p);
system.GetDSP().DoState(p);
p.DoMarker("DSP");
DVDInterface::DoState(p);
p.DoMarker("DVDInterface");
+1 -1
View File
@@ -54,7 +54,7 @@ void MemoryManager::InitMMIO(bool is_wii)
VideoInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C002000);
system.GetProcessorInterface().RegisterMMIO(m_mmio_mapping.get(), 0x0C003000);
MemoryInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C004000);
DSP::RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
system.GetDSP().RegisterMMIO(m_mmio_mapping.get(), 0x0C005000);
DVDInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006000, false);
SerialInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006400);
ExpansionInterface::RegisterMMIO(m_mmio_mapping.get(), 0x0C006800);
+4 -4
View File
@@ -97,9 +97,9 @@ void DSPCallback(Core::System& system, u64 userdata, s64 cyclesLate)
{
// splits up the cycle budget in case lle is used
// for hle, just gives all of the slice to hle
DSP::UpdateDSPSlice(static_cast<int>(DSP::GetDSPEmulator()->DSP_UpdateRate() - cyclesLate));
system.GetCoreTiming().ScheduleEvent(DSP::GetDSPEmulator()->DSP_UpdateRate() - cyclesLate,
et_DSP);
auto& dsp = system.GetDSP();
dsp.UpdateDSPSlice(static_cast<int>(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate));
system.GetCoreTiming().ScheduleEvent(dsp.GetDSPEmulator()->DSP_UpdateRate() - cyclesLate, et_DSP);
}
int GetAudioDMACallbackPeriod()
@@ -112,7 +112,7 @@ int GetAudioDMACallbackPeriod()
void AudioDMACallback(Core::System& system, u64 userdata, s64 cyclesLate)
{
DSP::UpdateAudioDMA(); // Push audio to speakers.
system.GetDSP().UpdateAudioDMA(); // Push audio to speakers.
system.GetCoreTiming().ScheduleEvent(GetAudioDMACallbackPeriod() - cyclesLate, et_AudioDMA);
}
+4 -3
View File
@@ -46,9 +46,10 @@ static void ReinitHardware()
PowerPC::Reset();
Wiimote::ResetAllWiimotes();
// Note: this is specific to Dolphin and is required because we initialised it in Wii mode.
DSP::Reinit(Config::Get(Config::MAIN_DSP_HLE));
DSP::GetDSPEmulator()->Initialize(SConfig::GetInstance().bWii,
Config::Get(Config::MAIN_DSP_THREAD));
auto& dsp = system.GetDSP();
dsp.Reinit(Config::Get(Config::MAIN_DSP_HLE));
dsp.GetDSPEmulator()->Initialize(SConfig::GetInstance().bWii,
Config::Get(Config::MAIN_DSP_THREAD));
SystemTimers::ChangePPCClock(SystemTimers::Mode::GC);
}
+4 -4
View File
@@ -36,7 +36,7 @@ namespace Core
struct System::Impl
{
explicit Impl(System& system)
: m_audio_interface(system), m_core_timing(system), m_gp_fifo(system),
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_gp_fifo(system),
m_ppc_state(PowerPC::ppcState)
{
}
@@ -49,7 +49,7 @@ struct System::Impl
CoreTiming::CoreTimingManager m_core_timing;
CommandProcessor::CommandProcessorManager m_command_processor;
CPU::CPUManager m_cpu;
DSP::DSPState m_dsp_state;
DSP::DSPManager m_dsp;
DVDInterface::DVDInterfaceState m_dvd_interface_state;
DVDThread::DVDThreadState m_dvd_thread_state;
ExpansionInterface::ExpansionInterfaceState m_expansion_interface_state;
@@ -133,9 +133,9 @@ CommandProcessor::CommandProcessorManager& System::GetCommandProcessor() const
return m_impl->m_command_processor;
}
DSP::DSPState& System::GetDSPState() const
DSP::DSPManager& System::GetDSP() const
{
return m_impl->m_dsp_state;
return m_impl->m_dsp;
}
DVDInterface::DVDInterfaceState& System::GetDVDInterfaceState() const
+2 -2
View File
@@ -29,7 +29,7 @@ class CoreTimingManager;
}
namespace DSP
{
class DSPState;
class DSPManager;
}
namespace DVDInterface
{
@@ -126,7 +126,7 @@ public:
CPU::CPUManager& GetCPU() const;
CoreTiming::CoreTimingManager& GetCoreTiming() const;
CommandProcessor::CommandProcessorManager& GetCommandProcessor() const;
DSP::DSPState& GetDSPState() const;
DSP::DSPManager& GetDSP() const;
DVDInterface::DVDInterfaceState& GetDVDInterfaceState() const;
DVDThread::DVDThreadState& GetDVDThreadState() const;
ExpansionInterface::ExpansionInterfaceState& GetExpansionInterfaceState() const;