Reworked DSP serialization

This commit is contained in:
Hamish Milne 2020-01-19 22:49:22 +00:00 committed by zhupengfei
parent 55c75b5e3e
commit c983528862
8 changed files with 128 additions and 13 deletions

2
externals/boost vendored

@ -1 +1 @@
Subproject commit 6d7edc593be8e47c8de7bc5f7d6b32971fad0c24
Subproject commit eb10fac1e1dfa4881c273d87e23d41509017223a

View file

@ -6,6 +6,7 @@
#include <memory>
#include <vector>
#include <boost/serialization/access.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/time_stretch.h"
#include "common/common_types.h"
@ -113,6 +114,10 @@ private:
Common::RingBuffer<s16, 0x2000, 2> fifo;
std::array<s16, 2> last_frame{};
TimeStretcher time_stretcher;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {}
friend class boost::serialization::access;
};
} // namespace AudioCore

View file

@ -1,7 +1,13 @@
#pragma optimize("", off)
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <boost/serialization/array.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/weak_ptr.hpp>
#include "audio_core/audio_types.h"
#ifdef HAVE_MF
#include "audio_core/hle/wmf_decoder.h"
@ -22,11 +28,21 @@
#include "core/core.h"
#include "core/core_timing.h"
SERIALIZE_EXPORT_IMPL(AudioCore::DspHle)
using InterruptType = Service::DSP::DSP_DSP::InterruptType;
using Service::DSP::DSP_DSP;
namespace AudioCore {
DspHle::DspHle() : DspHle(Core::System::GetInstance().Memory()) {}
template <class Archive>
void DspHle::serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<DspInterface>(*this);
ar&* impl.get();
}
static constexpr u64 audio_frame_ticks = 1310252ull; ///< Units: ARM11 cycles
struct DspHle::Impl final {
@ -60,7 +76,7 @@ private:
void AudioTickCallback(s64 cycles_late);
DspState dsp_state = DspState::Off;
std::array<std::vector<u8>, num_dsp_pipe> pipe_data;
std::array<std::vector<u8>, num_dsp_pipe> pipe_data{};
HLE::DspMemory dsp_memory;
std::array<HLE::Source, HLE::num_sources> sources{{
@ -70,14 +86,25 @@ private:
HLE::Source(15), HLE::Source(16), HLE::Source(17), HLE::Source(18), HLE::Source(19),
HLE::Source(20), HLE::Source(21), HLE::Source(22), HLE::Source(23),
}};
HLE::Mixers mixers;
HLE::Mixers mixers{};
DspHle& parent;
Core::TimingEventType* tick_event;
Core::TimingEventType* tick_event{};
std::unique_ptr<HLE::DecoderBase> decoder;
std::unique_ptr<HLE::DecoderBase> decoder{};
std::weak_ptr<DSP_DSP> dsp_dsp;
std::weak_ptr<DSP_DSP> dsp_dsp{};
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& dsp_state;
ar& pipe_data;
ar& dsp_memory.raw_memory;
ar& sources;
ar& mixers;
ar& dsp_dsp;
}
friend class boost::serialization::access;
};
DspHle::Impl::Impl(DspHle& parent_, Memory::MemorySystem& memory) : parent(parent_) {

View file

@ -7,6 +7,7 @@
#include <array>
#include <memory>
#include <vector>
#include <boost/serialization/export.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/dsp_interface.h"
#include "common/common_types.h"
@ -42,6 +43,14 @@ private:
struct Impl;
friend struct Impl;
std::unique_ptr<Impl> impl;
DspHle();
template <class Archive>
void serialize(Archive& ar, const unsigned int);
friend class boost::serialization::access;
};
} // namespace AudioCore
BOOST_CLASS_EXPORT_KEY(AudioCore::DspHle)

View file

@ -5,6 +5,7 @@
#pragma once
#include <array>
#include <boost/serialization/array.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/hle/shared_memory.h"
@ -54,6 +55,17 @@ private:
void DownmixAndMixIntoCurrentFrame(float gain, const QuadFrame32& samples);
/// INTERNAL: Generate DspStatus based on internal state.
DspStatus GetCurrentStatus() const;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& current_frame;
ar& state.intermediate_mixer_volume;
ar& state.mixer1_enabled;
ar& state.mixer2_enabled;
ar& state.intermediate_mix_buffer;
ar& state.output_format;
}
friend class boost::serialization::access;
};
} // namespace AudioCore::HLE

View file

@ -8,6 +8,7 @@
#include <cstddef>
#include <memory>
#include <type_traits>
#include <boost/serialization/access.hpp>
#include "audio_core/audio_types.h"
#include "audio_core/hle/common.h"
#include "common/bit_field.h"
@ -56,6 +57,12 @@ private:
return (value << 16) | (value >> 16);
}
u32_le storage;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& storage;
}
friend class boost::serialization::access;
};
static_assert(std::is_trivially_copyable<u32_dsp>::value, "u32_dsp isn't trivially copyable");

View file

@ -6,6 +6,10 @@
#include <array>
#include <vector>
#include <boost/serialization/array.hpp>
#include <boost/serialization/deque.hpp>
#include <boost/serialization/priority_queue.hpp>
#include <boost/serialization/vector.hpp>
#include <queue>
#include "audio_core/audio_types.h"
#include "audio_core/codec.h"
@ -85,6 +89,24 @@ private:
bool from_queue;
u32_dsp play_position; // = 0;
bool has_played; // = false;
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& physical_address;
ar& length;
ar& adpcm_ps;
ar& adpcm_yn;
ar& adpcm_dirty;
ar& is_looping;
ar& buffer_id;
ar& mono_or_stereo;
ar& format;
ar& from_queue;
ar& play_position;
ar& has_played;
}
friend class boost::serialization::access;
};
struct BufferOrder {
@ -107,7 +129,7 @@ private:
// Buffer queue
std::priority_queue<Buffer, std::vector<Buffer>, BufferOrder> input_queue;
std::priority_queue<Buffer, std::vector<Buffer>, BufferOrder> input_queue = {};
MonoOrStereo mono_or_stereo = MonoOrStereo::Mono;
Format format = Format::ADPCM;
@ -115,7 +137,7 @@ private:
u32 current_sample_number = 0;
u32 next_sample_number = 0;
AudioInterp::StereoBuffer16 current_buffer;
AudioInterp::StereoBuffer16 current_buffer = {};
// buffer_id state
@ -135,7 +157,27 @@ private:
// Filter state
SourceFilters filters;
SourceFilters filters = {};
private:
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& enabled;
ar& sync;
ar& gain;
ar& input_queue;
ar& mono_or_stereo;
ar& format;
ar& current_sample_number;
ar& next_sample_number;
ar& current_buffer;
ar& buffer_update;
ar& current_buffer_id;
ar& adpcm_coeffs;
ar& rate_multiplier;
ar& interpolation_mode;
}
friend class boost::serialization::access;
} state;
@ -150,6 +192,12 @@ private:
bool DequeueBuffer();
/// INTERNAL: Generates a SourceStatus::Status based on our internal state.
SourceStatus::Status GetCurrentStatus();
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& state;
}
friend class boost::serialization::access;
};
} // namespace AudioCore::HLE

View file

@ -1,3 +1,4 @@
#pragma optimize("", off)
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
@ -244,8 +245,8 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo
timing = std::make_unique<Timing>();
kernel = std::make_unique<Kernel::KernelSystem>(*memory, *timing,
[this] { PrepareReschedule(); }, system_mode);
kernel = std::make_unique<Kernel::KernelSystem>(
*memory, *timing, [this] { PrepareReschedule(); }, system_mode);
if (Settings::values.use_cpu_jit) {
#ifdef ARCHITECTURE_x86_64
@ -445,14 +446,20 @@ void System::serialize(Archive& ar, const unsigned int file_version) {
ar&* service_manager.get();
ar& GPU::g_regs;
ar& LCD::g_regs;
ar & dsp_core->GetDspMemory();
if (Archive::is_loading::value) {
dsp_core.reset();
}
ar& dsp_core;
ar&* memory.get();
ar&* kernel.get();
// This needs to be set from somewhere - might as well be here!
if (Archive::is_loading::value) {
Service::GSP::SetGlobalModule(*this);
DSP().SetServiceToInterrupt(ServiceManager().GetService<Service::DSP::DSP_DSP>("dsp::DSP"));
memory->SetDSP(*dsp_core);
dsp_core->SetSink(Settings::values.sink_id, Settings::values.audio_device_id);
dsp_core->EnableStretching(Settings::values.enable_audio_stretching);
}
}