Merge pull request #12487 from AdmiralCurtiss/globals-axaccel
Core/DSPHLE: Deglobalize HLEAccelerator state in AX and AXWii UCodes.
This commit is contained in:
commit
00fb709c74
|
@ -32,7 +32,16 @@ AXUCode::AXUCode(DSPHLE* dsphle, u32 crc) : UCodeInterface(dsphle, crc)
|
|||
INFO_LOG_FMT(DSPHLE, "Instantiating AXUCode: crc={:08x}", crc);
|
||||
}
|
||||
|
||||
AXUCode::~AXUCode() = default;
|
||||
|
||||
void AXUCode::Initialize()
|
||||
{
|
||||
InitializeShared();
|
||||
|
||||
m_accelerator = std::make_unique<HLEAccelerator>();
|
||||
}
|
||||
|
||||
void AXUCode::InitializeShared()
|
||||
{
|
||||
m_mail_handler.PushMail(DSP_INIT, true);
|
||||
|
||||
|
@ -421,7 +430,8 @@ void AXUCode::ProcessPBList(u32 pb_addr)
|
|||
{
|
||||
ApplyUpdatesForMs(curr_ms, pb, pb.updates.num_updates, updates);
|
||||
|
||||
ProcessVoice(pb, buffers, spms, ConvertMixerControl(pb.mixer_control),
|
||||
ProcessVoice(static_cast<HLEAccelerator*>(m_accelerator.get()), pb, buffers, spms,
|
||||
ConvertMixerControl(pb.mixer_control),
|
||||
m_coeffs_checksum ? m_coeffs.data() : nullptr);
|
||||
|
||||
// Forward the buffers
|
||||
|
@ -778,6 +788,8 @@ void AXUCode::DoAXState(PointerWrap& p)
|
|||
}
|
||||
|
||||
p.Do(m_compressor_pos);
|
||||
|
||||
m_accelerator->DoState(p);
|
||||
}
|
||||
|
||||
void AXUCode::DoState(PointerWrap& p)
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "Common/BitUtils.h"
|
||||
|
@ -21,6 +22,11 @@
|
|||
#include "Core/HW/Memmap.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
namespace DSP
|
||||
{
|
||||
class Accelerator;
|
||||
}
|
||||
|
||||
namespace DSP::HLE
|
||||
{
|
||||
class DSPHLE;
|
||||
|
@ -67,6 +73,7 @@ class AXUCode /* not final: subclassed by AXWiiUCode */ : public UCodeInterface
|
|||
{
|
||||
public:
|
||||
AXUCode(DSPHLE* dsphle, u32 crc);
|
||||
~AXUCode() override;
|
||||
|
||||
void Initialize() override;
|
||||
void HandleMail(u32 mail) override;
|
||||
|
@ -100,6 +107,10 @@ protected:
|
|||
|
||||
u16 m_compressor_pos = 0;
|
||||
|
||||
std::unique_ptr<Accelerator> m_accelerator;
|
||||
|
||||
void InitializeShared();
|
||||
|
||||
bool LoadResamplingCoefficients(bool require_same_checksum, u32 desired_checksum);
|
||||
|
||||
// Copy a command list from memory to our temp buffer
|
||||
|
|
|
@ -153,10 +153,11 @@ void WritePB(u32 addr, const PB_TYPE& pb, u32 crc)
|
|||
}
|
||||
|
||||
// Simulated accelerator state.
|
||||
static PB_TYPE* acc_pb;
|
||||
|
||||
class HLEAccelerator final : public Accelerator
|
||||
{
|
||||
public:
|
||||
PB_TYPE* acc_pb = nullptr;
|
||||
|
||||
protected:
|
||||
void OnEndException() override
|
||||
{
|
||||
|
@ -197,27 +198,25 @@ protected:
|
|||
}
|
||||
};
|
||||
|
||||
static std::unique_ptr<Accelerator> s_accelerator = std::make_unique<HLEAccelerator>();
|
||||
|
||||
// Sets up the simulated accelerator.
|
||||
void AcceleratorSetup(PB_TYPE* pb)
|
||||
void AcceleratorSetup(HLEAccelerator* accelerator, PB_TYPE* pb)
|
||||
{
|
||||
acc_pb = pb;
|
||||
s_accelerator->SetStartAddress(HILO_TO_32(pb->audio_addr.loop_addr));
|
||||
s_accelerator->SetEndAddress(HILO_TO_32(pb->audio_addr.end_addr));
|
||||
s_accelerator->SetCurrentAddress(HILO_TO_32(pb->audio_addr.cur_addr));
|
||||
s_accelerator->SetSampleFormat(pb->audio_addr.sample_format);
|
||||
s_accelerator->SetYn1(pb->adpcm.yn1);
|
||||
s_accelerator->SetYn2(pb->adpcm.yn2);
|
||||
s_accelerator->SetPredScale(pb->adpcm.pred_scale);
|
||||
accelerator->acc_pb = pb;
|
||||
accelerator->SetStartAddress(HILO_TO_32(pb->audio_addr.loop_addr));
|
||||
accelerator->SetEndAddress(HILO_TO_32(pb->audio_addr.end_addr));
|
||||
accelerator->SetCurrentAddress(HILO_TO_32(pb->audio_addr.cur_addr));
|
||||
accelerator->SetSampleFormat(pb->audio_addr.sample_format);
|
||||
accelerator->SetYn1(pb->adpcm.yn1);
|
||||
accelerator->SetYn2(pb->adpcm.yn2);
|
||||
accelerator->SetPredScale(pb->adpcm.pred_scale);
|
||||
}
|
||||
|
||||
// Reads a sample from the accelerator. Also handles looping and
|
||||
// disabling streams that reached the end (this is done by an exception raised
|
||||
// by the accelerator on real hardware).
|
||||
u16 AcceleratorGetSample()
|
||||
u16 AcceleratorGetSample(HLEAccelerator* accelerator)
|
||||
{
|
||||
return s_accelerator->Read(acc_pb->adpcm.coefs);
|
||||
return accelerator->Read(accelerator->acc_pb->adpcm.coefs);
|
||||
}
|
||||
|
||||
// Reads samples from the input callback, resamples them to <count> samples at
|
||||
|
@ -354,23 +353,24 @@ u32 ResampleAudio(std::function<s16(u32)> input_callback, s16* output, u32 count
|
|||
|
||||
// Read <count> input samples from ARAM, decoding and converting rate
|
||||
// if required.
|
||||
void GetInputSamples(PB_TYPE& pb, s16* samples, u16 count, const s16* coeffs)
|
||||
void GetInputSamples(HLEAccelerator* accelerator, PB_TYPE& pb, s16* samples, u16 count,
|
||||
const s16* coeffs)
|
||||
{
|
||||
AcceleratorSetup(&pb);
|
||||
AcceleratorSetup(accelerator, &pb);
|
||||
|
||||
if (coeffs)
|
||||
coeffs += pb.coef_select * 0x200;
|
||||
u32 curr_pos =
|
||||
ResampleAudio([](u32) { return AcceleratorGetSample(); }, samples, count, pb.src.last_samples,
|
||||
pb.src.cur_addr_frac, HILO_TO_32(pb.src.ratio), pb.src_type, coeffs);
|
||||
u32 curr_pos = ResampleAudio([accelerator](u32) { return AcceleratorGetSample(accelerator); },
|
||||
samples, count, pb.src.last_samples, pb.src.cur_addr_frac,
|
||||
HILO_TO_32(pb.src.ratio), pb.src_type, coeffs);
|
||||
pb.src.cur_addr_frac = (curr_pos & 0xFFFF);
|
||||
|
||||
// Update current position, YN1, YN2 and pred scale in the PB.
|
||||
pb.audio_addr.cur_addr_hi = static_cast<u16>(s_accelerator->GetCurrentAddress() >> 16);
|
||||
pb.audio_addr.cur_addr_lo = static_cast<u16>(s_accelerator->GetCurrentAddress());
|
||||
pb.adpcm.yn1 = s_accelerator->GetYn1();
|
||||
pb.adpcm.yn2 = s_accelerator->GetYn2();
|
||||
pb.adpcm.pred_scale = s_accelerator->GetPredScale();
|
||||
pb.audio_addr.cur_addr_hi = static_cast<u16>(accelerator->GetCurrentAddress() >> 16);
|
||||
pb.audio_addr.cur_addr_lo = static_cast<u16>(accelerator->GetCurrentAddress());
|
||||
pb.adpcm.yn1 = accelerator->GetYn1();
|
||||
pb.adpcm.yn2 = accelerator->GetYn2();
|
||||
pb.adpcm.pred_scale = accelerator->GetPredScale();
|
||||
}
|
||||
|
||||
// Add samples to an output buffer, with optional volume ramping.
|
||||
|
@ -410,8 +410,8 @@ s16 LowPassFilter(s16* samples, u32 count, s16 yn1, u16 a0, u16 b0)
|
|||
|
||||
// Process 1ms of audio (for AX GC) or 3ms of audio (for AX Wii) from a PB and
|
||||
// mix it to the output buffers.
|
||||
void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl mctrl,
|
||||
const s16* coeffs)
|
||||
void ProcessVoice(HLEAccelerator* accelerator, PB_TYPE& pb, const AXBuffers& buffers, u16 count,
|
||||
AXMixControl mctrl, const s16* coeffs)
|
||||
{
|
||||
// If the voice is not running, nothing to do.
|
||||
if (pb.running != 1)
|
||||
|
@ -419,7 +419,7 @@ void ProcessVoice(PB_TYPE& pb, const AXBuffers& buffers, u16 count, AXMixControl
|
|||
|
||||
// Read input samples, performing sample rate conversion if needed.
|
||||
s16 samples[MAX_SAMPLES_PER_FRAME];
|
||||
GetInputSamples(pb, samples, count, coeffs);
|
||||
GetInputSamples(accelerator, pb, samples, count, coeffs);
|
||||
|
||||
// Apply a global volume ramp using the volume envelope parameters.
|
||||
for (u32 i = 0; i < count; ++i)
|
||||
|
|
|
@ -30,6 +30,13 @@ AXWiiUCode::AXWiiUCode(DSPHLE* dsphle, u32 crc) : AXUCode(dsphle, crc), m_last_m
|
|||
m_old_axwii = (crc == 0xfa450138) || (crc == 0x7699af32);
|
||||
}
|
||||
|
||||
void AXWiiUCode::Initialize()
|
||||
{
|
||||
InitializeShared();
|
||||
|
||||
m_accelerator = std::make_unique<HLEAccelerator>();
|
||||
}
|
||||
|
||||
void AXWiiUCode::HandleCommandList()
|
||||
{
|
||||
// Temp variables for addresses computation
|
||||
|
@ -436,7 +443,8 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
|||
for (int curr_ms = 0; curr_ms < 3; ++curr_ms)
|
||||
{
|
||||
ApplyUpdatesForMs(curr_ms, pb, num_updates, updates);
|
||||
ProcessVoice(pb, buffers, spms, ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
|
||||
ProcessVoice(static_cast<HLEAccelerator*>(m_accelerator.get()), pb, buffers, spms,
|
||||
ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
|
||||
m_coeffs_checksum ? m_coeffs.data() : nullptr);
|
||||
|
||||
// Forward the buffers
|
||||
|
@ -447,7 +455,8 @@ void AXWiiUCode::ProcessPBList(u32 pb_addr)
|
|||
}
|
||||
else
|
||||
{
|
||||
ProcessVoice(pb, buffers, 96, ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
|
||||
ProcessVoice(static_cast<HLEAccelerator*>(m_accelerator.get()), pb, buffers, 96,
|
||||
ConvertMixerControl(HILO_TO_32(pb.mixer_control)),
|
||||
m_coeffs_checksum ? m_coeffs.data() : nullptr);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ class AXWiiUCode final : public AXUCode
|
|||
public:
|
||||
AXWiiUCode(DSPHLE* dsphle, u32 crc);
|
||||
|
||||
void Initialize() override;
|
||||
void DoState(PointerWrap& p) override;
|
||||
|
||||
protected:
|
||||
|
|
|
@ -95,7 +95,7 @@ static size_t s_state_writes_in_queue;
|
|||
static std::condition_variable s_state_write_queue_is_empty;
|
||||
|
||||
// Don't forget to increase this after doing changes on the savestate system
|
||||
constexpr u32 STATE_VERSION = 165; // Last changed in PR 12328
|
||||
constexpr u32 STATE_VERSION = 166; // Last changed in PR 12487
|
||||
|
||||
// Increase this if the StateExtendedHeader definition changes
|
||||
constexpr u32 EXTENDED_HEADER_VERSION = 1; // Last changed in PR 12217
|
||||
|
|
Loading…
Reference in New Issue