JIT optimizations and refactoring (#675)
* CPU/Recompiler: Use rel32 call where possible for no-args * JitCodeBuffer: Support using preallocated buffer * CPU/Recompiler/AArch64: Use bl instead of blr for short branches * CPU/CodeCache: Allocate recompiler buffer in program space This means we don't need 64-bit moves for every call out of the recompiler. * GTE: Don't store as u16 and load as u32 * CPU/Recompiler: Add methods to emit global load/stores * GTE: Convert class to namespace * CPU/Recompiler: Call GTE functions directly * Settings: Turn into a global variable * GPU: Replace local pointers with global * InterruptController: Turn into a global pointer * System: Replace local pointers with global * Timers: Turn into a global instance * DMA: Turn into a global instance * SPU: Turn into a global instance * CDROM: Turn into a global instance * MDEC: Turn into a global instance * Pad: Turn into a global instance * SIO: Turn into a global instance * CDROM: Move audio FIFO to the heap * CPU/Recompiler: Drop ASMFunctions No longer needed since we have code in the same 4GB window. * CPUCodeCache: Turn class into namespace * Bus: Local pointer -> global pointers * CPU: Turn class into namespace * Bus: Turn into namespace * GTE: Store registers in CPU state struct Allows relative addressing on ARM. * CPU/Recompiler: Align code storage to page size * CPU/Recompiler: Fix relative branches on A64 * HostInterface: Local references to global * System: Turn into a namespace, move events out * Add guard pages * Android: Fix build
This commit is contained in:
committed by
GitHub
parent
1f9fc6ab74
commit
b6f871d2b9
@ -11,21 +11,28 @@
|
||||
#include <imgui.h>
|
||||
Log_SetChannel(SPU);
|
||||
|
||||
SPU g_spu;
|
||||
|
||||
SPU::SPU() = default;
|
||||
|
||||
SPU::~SPU() = default;
|
||||
|
||||
void SPU::Initialize(System* system, DMA* dma, CDROM* cdrom, InterruptController* interrupt_controller)
|
||||
void SPU::Initialize()
|
||||
{
|
||||
m_system = system;
|
||||
m_dma = dma;
|
||||
m_cdrom = cdrom;
|
||||
m_interrupt_controller = interrupt_controller;
|
||||
m_tick_event = m_system->CreateTimingEvent("SPU Sample", SYSCLK_TICKS_PER_SPU_TICK, SYSCLK_TICKS_PER_SPU_TICK,
|
||||
std::bind(&SPU::Execute, this, std::placeholders::_1), false);
|
||||
m_tick_event = TimingEvents::CreateTimingEvent("SPU Sample", SYSCLK_TICKS_PER_SPU_TICK, SYSCLK_TICKS_PER_SPU_TICK,
|
||||
std::bind(&SPU::Execute, this, std::placeholders::_1), false);
|
||||
m_transfer_event =
|
||||
m_system->CreateTimingEvent("SPU Transfer", TRANSFER_TICKS_PER_HALFWORD, TRANSFER_TICKS_PER_HALFWORD,
|
||||
std::bind(&SPU::ExecuteTransfer, this, std::placeholders::_1), false);
|
||||
TimingEvents::CreateTimingEvent("SPU Transfer", TRANSFER_TICKS_PER_HALFWORD, TRANSFER_TICKS_PER_HALFWORD,
|
||||
std::bind(&SPU::ExecuteTransfer, this, std::placeholders::_1), false);
|
||||
|
||||
Reset();
|
||||
}
|
||||
|
||||
void SPU::Shutdown()
|
||||
{
|
||||
m_tick_event.reset();
|
||||
m_transfer_event.reset();
|
||||
m_dump_writer.reset();
|
||||
}
|
||||
|
||||
void SPU::Reset()
|
||||
@ -81,6 +88,7 @@ void SPU::Reset()
|
||||
}
|
||||
|
||||
m_transfer_fifo.Clear();
|
||||
m_transfer_event->Deactivate();
|
||||
m_ram.fill(0);
|
||||
UpdateEventInterval();
|
||||
}
|
||||
@ -147,7 +155,7 @@ bool SPU::DoState(StateWrapper& sw)
|
||||
|
||||
if (sw.IsReading())
|
||||
{
|
||||
m_system->GetHostInterface()->GetAudioStream()->EmptyBuffers();
|
||||
g_host_interface->GetAudioStream()->EmptyBuffers();
|
||||
UpdateEventInterval();
|
||||
UpdateTransferEvent();
|
||||
}
|
||||
@ -649,7 +657,7 @@ void SPU::CheckRAMIRQ(u32 address)
|
||||
{
|
||||
Log_DebugPrintf("SPU IRQ at address 0x%08X", address);
|
||||
m_SPUSTAT.irq9_flag = true;
|
||||
m_interrupt_controller->InterruptRequest(InterruptController::IRQ::SPU);
|
||||
g_interrupt_controller.InterruptRequest(InterruptController::IRQ::SPU);
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,7 +683,7 @@ void SPU::Execute(TickCount ticks)
|
||||
|
||||
while (remaining_frames > 0)
|
||||
{
|
||||
AudioStream* const output_stream = m_system->GetHostInterface()->GetAudioStream();
|
||||
AudioStream* const output_stream = g_host_interface->GetAudioStream();
|
||||
s16* output_frame_start;
|
||||
u32 output_frame_space = remaining_frames;
|
||||
output_stream->BeginWrite(&output_frame_start, &output_frame_space);
|
||||
@ -730,7 +738,7 @@ void SPU::Execute(TickCount ticks)
|
||||
UpdateNoise();
|
||||
|
||||
// Mix in CD audio.
|
||||
const auto [cd_audio_left, cd_audio_right] = m_cdrom->GetAudioFrame();
|
||||
const auto [cd_audio_left, cd_audio_right] = g_cdrom.GetAudioFrame();
|
||||
if (m_SPUCNT.cd_audio_enable)
|
||||
{
|
||||
const s32 cd_audio_volume_left = ApplyVolume(s32(cd_audio_left), m_cd_audio_volume_left);
|
||||
@ -782,7 +790,7 @@ void SPU::UpdateEventInterval()
|
||||
// Don't generate more than the audio buffer since in a single slice, otherwise we'll both overflow the buffers when
|
||||
// we do write it, and the audio thread will underflow since it won't have enough data it the game isn't messing with
|
||||
// the SPU state.
|
||||
const u32 max_slice_frames = m_system->GetHostInterface()->GetAudioStream()->GetBufferSize();
|
||||
const u32 max_slice_frames = g_host_interface->GetAudioStream()->GetBufferSize();
|
||||
|
||||
// TODO: Make this predict how long until the interrupt will be hit instead...
|
||||
const u32 interval = (m_SPUCNT.enable && m_SPUCNT.irq9_enable) ? 1 : max_slice_frames;
|
||||
@ -930,7 +938,7 @@ void SPU::UpdateDMARequest()
|
||||
}
|
||||
|
||||
// This might call us back directly.
|
||||
m_dma->SetRequest(DMA::Channel::SPU, m_SPUSTAT.dma_request);
|
||||
g_dma.SetRequest(DMA::Channel::SPU, m_SPUSTAT.dma_request);
|
||||
}
|
||||
|
||||
void SPU::DMARead(u32* words, u32 word_count)
|
||||
@ -1744,7 +1752,7 @@ void SPU::DrawDebugStateWindow()
|
||||
const float framebuffer_scale = ImGui::GetIO().DisplayFramebufferScale.x;
|
||||
|
||||
ImGui::SetNextWindowSize(ImVec2(800.0f * framebuffer_scale, 800.0f * framebuffer_scale), ImGuiCond_FirstUseEver);
|
||||
if (!ImGui::Begin("SPU State", &m_system->GetSettings().debugging.show_spu_state))
|
||||
if (!ImGui::Begin("SPU State", &g_settings.debugging.show_spu_state))
|
||||
{
|
||||
ImGui::End();
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user