Removing apu/ deps on Emulator.
This commit is contained in:
parent
ad090a40eb
commit
19299fad4b
|
@ -9,15 +9,10 @@
|
||||||
|
|
||||||
#include "xenia/apu/audio_driver.h"
|
#include "xenia/apu/audio_driver.h"
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
|
||||||
#include "xenia/cpu/processor.h"
|
|
||||||
#include "xenia/cpu/thread_state.h"
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
|
||||||
AudioDriver::AudioDriver(Emulator* emulator)
|
AudioDriver::AudioDriver(Memory* memory) : memory_(memory) {}
|
||||||
: emulator_(emulator), memory_(emulator->memory()) {}
|
|
||||||
|
|
||||||
AudioDriver::~AudioDriver() = default;
|
AudioDriver::~AudioDriver() = default;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
#ifndef XENIA_APU_AUDIO_DRIVER_H_
|
#ifndef XENIA_APU_AUDIO_DRIVER_H_
|
||||||
#define XENIA_APU_AUDIO_DRIVER_H_
|
#define XENIA_APU_AUDIO_DRIVER_H_
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
|
@ -18,7 +18,7 @@ namespace apu {
|
||||||
|
|
||||||
class AudioDriver {
|
class AudioDriver {
|
||||||
public:
|
public:
|
||||||
explicit AudioDriver(Emulator* emulator);
|
explicit AudioDriver(Memory* memory);
|
||||||
virtual ~AudioDriver();
|
virtual ~AudioDriver();
|
||||||
|
|
||||||
virtual void SubmitFrame(uint32_t samples_ptr) = 0;
|
virtual void SubmitFrame(uint32_t samples_ptr) = 0;
|
||||||
|
@ -28,9 +28,7 @@ class AudioDriver {
|
||||||
return memory_->TranslatePhysical(guest_address);
|
return memory_->TranslatePhysical(guest_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
Emulator* emulator_;
|
Memory* memory_ = nullptr;
|
||||||
Memory* memory_;
|
|
||||||
cpu::Processor* processor_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace apu
|
} // namespace apu
|
||||||
|
|
|
@ -11,15 +11,13 @@
|
||||||
|
|
||||||
#include "xenia/apu/apu_flags.h"
|
#include "xenia/apu/apu_flags.h"
|
||||||
#include "xenia/apu/audio_driver.h"
|
#include "xenia/apu/audio_driver.h"
|
||||||
|
#include "xenia/apu/xma_decoder.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/base/math.h"
|
#include "xenia/base/math.h"
|
||||||
#include "xenia/base/ring_buffer.h"
|
#include "xenia/base/ring_buffer.h"
|
||||||
#include "xenia/base/string_buffer.h"
|
#include "xenia/base/string_buffer.h"
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/cpu/processor.h"
|
|
||||||
#include "xenia/cpu/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/emulator.h"
|
|
||||||
#include "xenia/kernel/objects/xthread.h"
|
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
#include "xenia/apu/nop/nop_audio_system.h"
|
#include "xenia/apu/nop/nop_audio_system.h"
|
||||||
|
@ -42,31 +40,33 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
|
||||||
std::unique_ptr<AudioSystem> AudioSystem::Create(Emulator* emulator) {
|
std::unique_ptr<AudioSystem> AudioSystem::Create(cpu::Processor* processor) {
|
||||||
if (FLAGS_apu.compare("nop") == 0) {
|
if (FLAGS_apu.compare("nop") == 0) {
|
||||||
return nop::NopAudioSystem::Create(emulator);
|
return nop::NopAudioSystem::Create(processor);
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
} else if (FLAGS_apu.compare("xaudio2") == 0) {
|
} else if (FLAGS_apu.compare("xaudio2") == 0) {
|
||||||
return xaudio2::XAudio2AudioSystem::Create(emulator);
|
return xaudio2::XAudio2AudioSystem::Create(processor);
|
||||||
#endif // WIN32
|
#endif // WIN32
|
||||||
} else {
|
} else {
|
||||||
// Create best available.
|
// Create best available.
|
||||||
std::unique_ptr<AudioSystem> best;
|
std::unique_ptr<AudioSystem> best;
|
||||||
|
|
||||||
#if XE_PLATFORM_WIN32
|
#if XE_PLATFORM_WIN32
|
||||||
best = xaudio2::XAudio2AudioSystem::Create(emulator);
|
best = xaudio2::XAudio2AudioSystem::Create(processor);
|
||||||
if (best) {
|
if (best) {
|
||||||
return best;
|
return best;
|
||||||
}
|
}
|
||||||
#endif // XE_PLATFORM_WIN32
|
#endif // XE_PLATFORM_WIN32
|
||||||
|
|
||||||
// Fallback to nop.
|
// Fallback to nop.
|
||||||
return nop::NopAudioSystem::Create(emulator);
|
return nop::NopAudioSystem::Create(processor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioSystem::AudioSystem(Emulator* emulator)
|
AudioSystem::AudioSystem(cpu::Processor* processor)
|
||||||
: emulator_(emulator), memory_(emulator->memory()), worker_running_(false) {
|
: memory_(processor->memory()),
|
||||||
|
processor_(processor),
|
||||||
|
worker_running_(false) {
|
||||||
std::memset(clients_, 0, sizeof(clients_));
|
std::memset(clients_, 0, sizeof(clients_));
|
||||||
for (size_t i = 0; i < kMaximumClientCount; ++i) {
|
for (size_t i = 0; i < kMaximumClientCount; ++i) {
|
||||||
unused_clients_.push(i);
|
unused_clients_.push(i);
|
||||||
|
@ -78,20 +78,28 @@ AudioSystem::AudioSystem(Emulator* emulator)
|
||||||
}
|
}
|
||||||
shutdown_event_ = xe::threading::Event::CreateManualResetEvent(false);
|
shutdown_event_ = xe::threading::Event::CreateManualResetEvent(false);
|
||||||
wait_handles_[kMaximumClientCount] = shutdown_event_.get();
|
wait_handles_[kMaximumClientCount] = shutdown_event_.get();
|
||||||
|
|
||||||
|
xma_decoder_ = std::make_unique<xe::apu::XmaDecoder>(processor_);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioSystem::~AudioSystem() = default;
|
AudioSystem::~AudioSystem() {
|
||||||
|
if (xma_decoder_) {
|
||||||
|
xma_decoder_->Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
X_STATUS AudioSystem::Setup() {
|
X_STATUS AudioSystem::Setup(kernel::KernelState* kernel_state) {
|
||||||
processor_ = emulator_->processor();
|
X_STATUS result = xma_decoder_->Setup(kernel_state);
|
||||||
|
if (result) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
worker_running_ = true;
|
worker_running_ = true;
|
||||||
worker_thread_ =
|
worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
||||||
kernel::object_ref<kernel::XHostThread>(new kernel::XHostThread(
|
new kernel::XHostThread(kernel_state, 128 * 1024, 0, [this]() {
|
||||||
emulator()->kernel_state(), 128 * 1024, 0, [this]() {
|
WorkerThreadMain();
|
||||||
WorkerThreadMain();
|
return 0;
|
||||||
return 0;
|
}));
|
||||||
}));
|
|
||||||
worker_thread_->set_name("Audio Worker");
|
worker_thread_->set_name("Audio Worker");
|
||||||
worker_thread_->Create();
|
worker_thread_->Create();
|
||||||
|
|
||||||
|
@ -102,8 +110,6 @@ void AudioSystem::WorkerThreadMain() {
|
||||||
// Initialize driver and ringbuffer.
|
// Initialize driver and ringbuffer.
|
||||||
Initialize();
|
Initialize();
|
||||||
|
|
||||||
auto processor = emulator_->processor();
|
|
||||||
|
|
||||||
// Main run loop.
|
// Main run loop.
|
||||||
while (worker_running_) {
|
while (worker_running_) {
|
||||||
auto result =
|
auto result =
|
||||||
|
@ -126,8 +132,8 @@ void AudioSystem::WorkerThreadMain() {
|
||||||
if (client_callback) {
|
if (client_callback) {
|
||||||
SCOPE_profile_cpu_i("apu", "xe::apu::AudioSystem->client_callback");
|
SCOPE_profile_cpu_i("apu", "xe::apu::AudioSystem->client_callback");
|
||||||
uint64_t args[] = {client_callback_arg};
|
uint64_t args[] = {client_callback_arg};
|
||||||
processor->Execute(worker_thread_->thread_state(), client_callback,
|
processor_->Execute(worker_thread_->thread_state(), client_callback,
|
||||||
args, xe::countof(args));
|
args, xe::countof(args));
|
||||||
}
|
}
|
||||||
pumped++;
|
pumped++;
|
||||||
index++;
|
index++;
|
||||||
|
|
|
@ -15,31 +15,28 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "xenia/base/threading.h"
|
#include "xenia/base/threading.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/cpu/processor.h"
|
||||||
|
#include "xenia/kernel/objects/xthread.h"
|
||||||
|
#include "xenia/memory.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace kernel {
|
|
||||||
class XHostThread;
|
|
||||||
} // namespace kernel
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
|
||||||
class AudioDriver;
|
class AudioDriver;
|
||||||
|
class XmaDecoder;
|
||||||
|
|
||||||
class AudioSystem {
|
class AudioSystem {
|
||||||
public:
|
public:
|
||||||
virtual ~AudioSystem();
|
virtual ~AudioSystem();
|
||||||
|
|
||||||
static std::unique_ptr<AudioSystem> Create(Emulator* emulator);
|
static std::unique_ptr<AudioSystem> Create(cpu::Processor* processor);
|
||||||
|
|
||||||
Emulator* emulator() const { return emulator_; }
|
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
cpu::Processor* processor() const { return processor_; }
|
cpu::Processor* processor() const { return processor_; }
|
||||||
|
XmaDecoder* xma_decoder() const { return xma_decoder_.get(); }
|
||||||
|
|
||||||
virtual X_STATUS Setup();
|
virtual X_STATUS Setup(kernel::KernelState* kernel_state);
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
|
|
||||||
X_STATUS RegisterClient(uint32_t callback, uint32_t callback_arg,
|
X_STATUS RegisterClient(uint32_t callback, uint32_t callback_arg,
|
||||||
|
@ -48,7 +45,7 @@ class AudioSystem {
|
||||||
void SubmitFrame(size_t index, uint32_t samples_ptr);
|
void SubmitFrame(size_t index, uint32_t samples_ptr);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit AudioSystem(Emulator* emulator);
|
explicit AudioSystem(cpu::Processor* processor);
|
||||||
|
|
||||||
virtual void Initialize();
|
virtual void Initialize();
|
||||||
|
|
||||||
|
@ -63,11 +60,11 @@ class AudioSystem {
|
||||||
// XAUDIO2_MAX_QUEUED_BUFFERS))
|
// XAUDIO2_MAX_QUEUED_BUFFERS))
|
||||||
static const size_t kMaximumQueuedFrames = 64;
|
static const size_t kMaximumQueuedFrames = 64;
|
||||||
|
|
||||||
Emulator* emulator_;
|
Memory* memory_ = nullptr;
|
||||||
Memory* memory_;
|
cpu::Processor* processor_ = nullptr;
|
||||||
cpu::Processor* processor_;
|
std::unique_ptr<XmaDecoder> xma_decoder_;
|
||||||
|
|
||||||
std::atomic<bool> worker_running_;
|
std::atomic<bool> worker_running_ = {false};
|
||||||
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
||||||
|
|
||||||
xe::mutex lock_;
|
xe::mutex lock_;
|
||||||
|
|
|
@ -15,11 +15,12 @@ namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
namespace nop {
|
namespace nop {
|
||||||
|
|
||||||
std::unique_ptr<AudioSystem> NopAudioSystem::Create(Emulator* emulator) {
|
std::unique_ptr<AudioSystem> NopAudioSystem::Create(cpu::Processor* processor) {
|
||||||
return std::make_unique<NopAudioSystem>(emulator);
|
return std::make_unique<NopAudioSystem>(processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
NopAudioSystem::NopAudioSystem(Emulator* emulator) : AudioSystem(emulator) {}
|
NopAudioSystem::NopAudioSystem(cpu::Processor* processor)
|
||||||
|
: AudioSystem(processor) {}
|
||||||
|
|
||||||
NopAudioSystem::~NopAudioSystem() = default;
|
NopAudioSystem::~NopAudioSystem() = default;
|
||||||
|
|
||||||
|
|
|
@ -18,10 +18,10 @@ namespace nop {
|
||||||
|
|
||||||
class NopAudioSystem : public AudioSystem {
|
class NopAudioSystem : public AudioSystem {
|
||||||
public:
|
public:
|
||||||
explicit NopAudioSystem(Emulator* emulator);
|
explicit NopAudioSystem(cpu::Processor* processor);
|
||||||
~NopAudioSystem() override;
|
~NopAudioSystem() override;
|
||||||
|
|
||||||
static std::unique_ptr<AudioSystem> Create(Emulator* emulator);
|
static std::unique_ptr<AudioSystem> Create(cpu::Processor* processor);
|
||||||
|
|
||||||
X_STATUS CreateDriver(size_t index, xe::threading::Semaphore* semaphore,
|
X_STATUS CreateDriver(size_t index, xe::threading::Semaphore* semaphore,
|
||||||
AudioDriver** out_driver) override;
|
AudioDriver** out_driver) override;
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
#include "xenia/apu/apu_flags.h"
|
#include "xenia/apu/apu_flags.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
#include "xenia/emulator.h"
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
@ -43,9 +42,9 @@ class XAudio2AudioDriver::VoiceCallback : public IXAudio2VoiceCallback {
|
||||||
xe::threading::Semaphore* semaphore_ = nullptr;
|
xe::threading::Semaphore* semaphore_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
XAudio2AudioDriver::XAudio2AudioDriver(Emulator* emulator,
|
XAudio2AudioDriver::XAudio2AudioDriver(Memory* memory,
|
||||||
xe::threading::Semaphore* semaphore)
|
xe::threading::Semaphore* semaphore)
|
||||||
: AudioDriver(emulator), semaphore_(semaphore) {
|
: AudioDriver(memory), semaphore_(semaphore) {
|
||||||
static_assert(frame_count_ == XAUDIO2_MAX_QUEUED_BUFFERS,
|
static_assert(frame_count_ == XAUDIO2_MAX_QUEUED_BUFFERS,
|
||||||
"xaudio header differs");
|
"xaudio header differs");
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_
|
#define XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_
|
||||||
|
|
||||||
#include "xenia/apu/audio_driver.h"
|
#include "xenia/apu/audio_driver.h"
|
||||||
|
#include "xenia/base/threading.h"
|
||||||
|
|
||||||
struct IXAudio2;
|
struct IXAudio2;
|
||||||
struct IXAudio2MasteringVoice;
|
struct IXAudio2MasteringVoice;
|
||||||
|
@ -22,7 +23,7 @@ namespace xaudio2 {
|
||||||
|
|
||||||
class XAudio2AudioDriver : public AudioDriver {
|
class XAudio2AudioDriver : public AudioDriver {
|
||||||
public:
|
public:
|
||||||
XAudio2AudioDriver(Emulator* emulator, xe::threading::Semaphore* semaphore);
|
XAudio2AudioDriver(Memory* memory, xe::threading::Semaphore* semaphore);
|
||||||
~XAudio2AudioDriver() override;
|
~XAudio2AudioDriver() override;
|
||||||
|
|
||||||
void Initialize();
|
void Initialize();
|
||||||
|
|
|
@ -13,18 +13,18 @@
|
||||||
|
|
||||||
#include "xenia/apu/apu_flags.h"
|
#include "xenia/apu/apu_flags.h"
|
||||||
#include "xenia/apu/xaudio2/xaudio2_audio_driver.h"
|
#include "xenia/apu/xaudio2/xaudio2_audio_driver.h"
|
||||||
#include "xenia/emulator.h"
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
namespace xaudio2 {
|
namespace xaudio2 {
|
||||||
|
|
||||||
std::unique_ptr<AudioSystem> XAudio2AudioSystem::Create(Emulator* emulator) {
|
std::unique_ptr<AudioSystem> XAudio2AudioSystem::Create(
|
||||||
return std::make_unique<XAudio2AudioSystem>(emulator);
|
cpu::Processor* processor) {
|
||||||
|
return std::make_unique<XAudio2AudioSystem>(processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
XAudio2AudioSystem::XAudio2AudioSystem(Emulator* emulator)
|
XAudio2AudioSystem::XAudio2AudioSystem(cpu::Processor* processor)
|
||||||
: AudioSystem(emulator) {}
|
: AudioSystem(processor) {}
|
||||||
|
|
||||||
XAudio2AudioSystem::~XAudio2AudioSystem() {}
|
XAudio2AudioSystem::~XAudio2AudioSystem() {}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ X_STATUS XAudio2AudioSystem::CreateDriver(size_t index,
|
||||||
xe::threading::Semaphore* semaphore,
|
xe::threading::Semaphore* semaphore,
|
||||||
AudioDriver** out_driver) {
|
AudioDriver** out_driver) {
|
||||||
assert_not_null(out_driver);
|
assert_not_null(out_driver);
|
||||||
auto driver = new XAudio2AudioDriver(emulator_, semaphore);
|
auto driver = new XAudio2AudioDriver(memory_, semaphore);
|
||||||
driver->Initialize();
|
driver->Initialize();
|
||||||
*out_driver = driver;
|
*out_driver = driver;
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
|
|
|
@ -18,10 +18,10 @@ namespace xaudio2 {
|
||||||
|
|
||||||
class XAudio2AudioSystem : public AudioSystem {
|
class XAudio2AudioSystem : public AudioSystem {
|
||||||
public:
|
public:
|
||||||
explicit XAudio2AudioSystem(Emulator* emulator);
|
explicit XAudio2AudioSystem(cpu::Processor* processor);
|
||||||
~XAudio2AudioSystem() override;
|
~XAudio2AudioSystem() override;
|
||||||
|
|
||||||
static std::unique_ptr<AudioSystem> Create(Emulator* emulator);
|
static std::unique_ptr<AudioSystem> Create(cpu::Processor* processor);
|
||||||
|
|
||||||
X_RESULT CreateDriver(size_t index, xe::threading::Semaphore* semaphore,
|
X_RESULT CreateDriver(size_t index, xe::threading::Semaphore* semaphore,
|
||||||
AudioDriver** out_driver) override;
|
AudioDriver** out_driver) override;
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/memory.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
// XMA audio format:
|
// XMA audio format:
|
||||||
|
@ -174,7 +174,7 @@ class XmaContext {
|
||||||
int DecodePacket(uint8_t* output, size_t offset, size_t size,
|
int DecodePacket(uint8_t* output, size_t offset, size_t size,
|
||||||
size_t* read_bytes);
|
size_t* read_bytes);
|
||||||
|
|
||||||
Memory* memory_;
|
Memory* memory_ = nullptr;
|
||||||
|
|
||||||
uint32_t id_ = 0;
|
uint32_t id_ = 0;
|
||||||
uint32_t guest_ptr_ = 0;
|
uint32_t guest_ptr_ = 0;
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "xenia/base/string_buffer.h"
|
#include "xenia/base/string_buffer.h"
|
||||||
#include "xenia/cpu/processor.h"
|
#include "xenia/cpu/processor.h"
|
||||||
#include "xenia/cpu/thread_state.h"
|
#include "xenia/cpu/thread_state.h"
|
||||||
#include "xenia/emulator.h"
|
|
||||||
#include "xenia/kernel/objects/xthread.h"
|
#include "xenia/kernel/objects/xthread.h"
|
||||||
#include "xenia/profiling.h"
|
#include "xenia/profiling.h"
|
||||||
|
|
||||||
|
@ -50,15 +49,10 @@ extern "C" {
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
|
||||||
XmaDecoder::XmaDecoder(Emulator* emulator)
|
XmaDecoder::XmaDecoder(cpu::Processor* processor)
|
||||||
: emulator_(emulator),
|
: memory_(processor->memory()), processor_(processor) {}
|
||||||
memory_(emulator->memory()),
|
|
||||||
processor_(emulator->processor()),
|
|
||||||
worker_running_(false),
|
|
||||||
context_data_first_ptr_(0),
|
|
||||||
context_data_last_ptr_(0) {}
|
|
||||||
|
|
||||||
XmaDecoder::~XmaDecoder() {}
|
XmaDecoder::~XmaDecoder() = default;
|
||||||
|
|
||||||
void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
|
void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
|
||||||
StringBuffer buff;
|
StringBuffer buff;
|
||||||
|
@ -66,12 +60,12 @@ void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
|
||||||
xe::log_line('i', "libav: %s", buff.GetString());
|
xe::log_line('i', "libav: %s", buff.GetString());
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS XmaDecoder::Setup() {
|
X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) {
|
||||||
// Setup libav logging callback
|
// Setup libav logging callback
|
||||||
av_log_set_callback(av_log_callback);
|
av_log_set_callback(av_log_callback);
|
||||||
|
|
||||||
// Let the processor know we want register access callbacks.
|
// Let the processor know we want register access callbacks.
|
||||||
emulator_->memory()->AddVirtualMappedRange(
|
memory_->AddVirtualMappedRange(
|
||||||
0x7FEA0000, 0xFFFF0000, 0x0000FFFF, this,
|
0x7FEA0000, 0xFFFF0000, 0x0000FFFF, this,
|
||||||
reinterpret_cast<cpu::MMIOReadCallback>(MMIOReadRegisterThunk),
|
reinterpret_cast<cpu::MMIOReadCallback>(MMIOReadRegisterThunk),
|
||||||
reinterpret_cast<cpu::MMIOWriteCallback>(MMIOWriteRegisterThunk));
|
reinterpret_cast<cpu::MMIOWriteCallback>(MMIOWriteRegisterThunk));
|
||||||
|
@ -95,12 +89,11 @@ X_STATUS XmaDecoder::Setup() {
|
||||||
registers_.next_context = 1;
|
registers_.next_context = 1;
|
||||||
|
|
||||||
worker_running_ = true;
|
worker_running_ = true;
|
||||||
worker_thread_ =
|
worker_thread_ = kernel::object_ref<kernel::XHostThread>(
|
||||||
kernel::object_ref<kernel::XHostThread>(new kernel::XHostThread(
|
new kernel::XHostThread(kernel_state, 128 * 1024, 0, [this]() {
|
||||||
emulator()->kernel_state(), 128 * 1024, 0, [this]() {
|
WorkerThreadMain();
|
||||||
WorkerThreadMain();
|
return 0;
|
||||||
return 0;
|
}));
|
||||||
}));
|
|
||||||
worker_thread_->set_name("XMA Decoder Worker");
|
worker_thread_->set_name("XMA Decoder Worker");
|
||||||
worker_thread_->Create();
|
worker_thread_->Create();
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,9 @@
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
#include "xenia/apu/xma_context.h"
|
#include "xenia/apu/xma_context.h"
|
||||||
#include "xenia/emulator.h"
|
#include "xenia/kernel/objects/xthread.h"
|
||||||
#include "xenia/xbox.h"
|
#include "xenia/xbox.h"
|
||||||
|
|
||||||
namespace xe {
|
|
||||||
namespace kernel {
|
|
||||||
class XHostThread;
|
|
||||||
} // namespace kernel
|
|
||||||
} // namespace xe
|
|
||||||
|
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
|
|
||||||
|
@ -31,15 +25,14 @@ struct XMA_CONTEXT_DATA;
|
||||||
|
|
||||||
class XmaDecoder {
|
class XmaDecoder {
|
||||||
public:
|
public:
|
||||||
explicit XmaDecoder(Emulator* emulator);
|
explicit XmaDecoder(cpu::Processor* processor);
|
||||||
~XmaDecoder();
|
~XmaDecoder();
|
||||||
|
|
||||||
Emulator* emulator() const { return emulator_; }
|
|
||||||
Memory* memory() const { return memory_; }
|
Memory* memory() const { return memory_; }
|
||||||
cpu::Processor* processor() const { return processor_; }
|
cpu::Processor* processor() const { return processor_; }
|
||||||
|
|
||||||
virtual X_STATUS Setup();
|
X_STATUS Setup(kernel::KernelState* kernel_state);
|
||||||
virtual void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
uint32_t context_array_ptr() const { return registers_.context_array_ptr; }
|
uint32_t context_array_ptr() const { return registers_.context_array_ptr; }
|
||||||
|
|
||||||
|
@ -47,8 +40,8 @@ class XmaDecoder {
|
||||||
void ReleaseContext(uint32_t guest_ptr);
|
void ReleaseContext(uint32_t guest_ptr);
|
||||||
bool BlockOnContext(uint32_t guest_ptr, bool poll);
|
bool BlockOnContext(uint32_t guest_ptr, bool poll);
|
||||||
|
|
||||||
virtual uint32_t ReadRegister(uint32_t addr);
|
uint32_t ReadRegister(uint32_t addr);
|
||||||
virtual void WriteRegister(uint32_t addr, uint32_t value);
|
void WriteRegister(uint32_t addr, uint32_t value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int GetContextId(uint32_t guest_ptr);
|
int GetContextId(uint32_t guest_ptr);
|
||||||
|
@ -66,11 +59,10 @@ class XmaDecoder {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Emulator* emulator_;
|
Memory* memory_ = nullptr;
|
||||||
Memory* memory_;
|
cpu::Processor* processor_ = nullptr;
|
||||||
cpu::Processor* processor_;
|
|
||||||
|
|
||||||
std::atomic<bool> worker_running_;
|
std::atomic<bool> worker_running_ = {false};
|
||||||
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
kernel::object_ref<kernel::XHostThread> worker_thread_;
|
||||||
xe::threading::Fence worker_fence_;
|
xe::threading::Fence worker_fence_;
|
||||||
|
|
||||||
|
@ -100,8 +92,8 @@ class XmaDecoder {
|
||||||
static const uint32_t kContextCount = 320;
|
static const uint32_t kContextCount = 320;
|
||||||
XmaContext contexts_[kContextCount];
|
XmaContext contexts_[kContextCount];
|
||||||
|
|
||||||
uint32_t context_data_first_ptr_;
|
uint32_t context_data_first_ptr_ = 0;
|
||||||
uint32_t context_data_last_ptr_;
|
uint32_t context_data_last_ptr_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace apu
|
} // namespace apu
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <gflags/gflags.h>
|
#include <gflags/gflags.h>
|
||||||
|
|
||||||
#include "xenia/apu/audio_system.h"
|
#include "xenia/apu/audio_system.h"
|
||||||
#include "xenia/apu/xma_decoder.h"
|
|
||||||
#include "xenia/base/assert.h"
|
#include "xenia/base/assert.h"
|
||||||
#include "xenia/base/clock.h"
|
#include "xenia/base/clock.h"
|
||||||
#include "xenia/base/logging.h"
|
#include "xenia/base/logging.h"
|
||||||
|
@ -47,12 +46,10 @@ Emulator::~Emulator() {
|
||||||
// Give the systems time to shutdown before we delete them.
|
// Give the systems time to shutdown before we delete them.
|
||||||
graphics_system_->Shutdown();
|
graphics_system_->Shutdown();
|
||||||
audio_system_->Shutdown();
|
audio_system_->Shutdown();
|
||||||
xma_decoder_->Shutdown();
|
|
||||||
|
|
||||||
input_system_.reset();
|
input_system_.reset();
|
||||||
graphics_system_.reset();
|
graphics_system_.reset();
|
||||||
audio_system_.reset();
|
audio_system_.reset();
|
||||||
xma_decoder_.reset();
|
|
||||||
|
|
||||||
kernel_state_.reset();
|
kernel_state_.reset();
|
||||||
file_system_.reset();
|
file_system_.reset();
|
||||||
|
@ -104,13 +101,11 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
||||||
memory_.get(), export_resolver_.get(), debugger_.get());
|
memory_.get(), export_resolver_.get(), debugger_.get());
|
||||||
|
|
||||||
// Initialize the APU.
|
// Initialize the APU.
|
||||||
audio_system_ = xe::apu::AudioSystem::Create(this);
|
audio_system_ = xe::apu::AudioSystem::Create(processor_.get());
|
||||||
if (!audio_system_) {
|
if (!audio_system_) {
|
||||||
return X_STATUS_NOT_IMPLEMENTED;
|
return X_STATUS_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
xma_decoder_ = std::make_unique<xe::apu::XmaDecoder>(this);
|
|
||||||
|
|
||||||
// Initialize the GPU.
|
// Initialize the GPU.
|
||||||
graphics_system_ = xe::gpu::GraphicsSystem::Create(this);
|
graphics_system_ = xe::gpu::GraphicsSystem::Create(this);
|
||||||
if (!graphics_system_) {
|
if (!graphics_system_) {
|
||||||
|
@ -148,12 +143,7 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = audio_system_->Setup();
|
result = audio_system_->Setup(kernel_state_.get());
|
||||||
if (result) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = xma_decoder_->Setup();
|
|
||||||
if (result) {
|
if (result) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
namespace xe {
|
namespace xe {
|
||||||
namespace apu {
|
namespace apu {
|
||||||
class AudioSystem;
|
class AudioSystem;
|
||||||
class XmaDecoder;
|
|
||||||
} // namespace apu
|
} // namespace apu
|
||||||
namespace cpu {
|
namespace cpu {
|
||||||
class ExportResolver;
|
class ExportResolver;
|
||||||
|
@ -56,7 +55,6 @@ class Emulator {
|
||||||
|
|
||||||
cpu::Processor* processor() const { return processor_.get(); }
|
cpu::Processor* processor() const { return processor_.get(); }
|
||||||
apu::AudioSystem* audio_system() const { return audio_system_.get(); }
|
apu::AudioSystem* audio_system() const { return audio_system_.get(); }
|
||||||
apu::XmaDecoder* xma_decoder() const { return xma_decoder_.get(); }
|
|
||||||
gpu::GraphicsSystem* graphics_system() const {
|
gpu::GraphicsSystem* graphics_system() const {
|
||||||
return graphics_system_.get();
|
return graphics_system_.get();
|
||||||
}
|
}
|
||||||
|
@ -90,7 +88,6 @@ class Emulator {
|
||||||
|
|
||||||
std::unique_ptr<cpu::Processor> processor_;
|
std::unique_ptr<cpu::Processor> processor_;
|
||||||
std::unique_ptr<apu::AudioSystem> audio_system_;
|
std::unique_ptr<apu::AudioSystem> audio_system_;
|
||||||
std::unique_ptr<apu::XmaDecoder> xma_decoder_;
|
|
||||||
std::unique_ptr<gpu::GraphicsSystem> graphics_system_;
|
std::unique_ptr<gpu::GraphicsSystem> graphics_system_;
|
||||||
std::unique_ptr<hid::InputSystem> input_system_;
|
std::unique_ptr<hid::InputSystem> input_system_;
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ SHIM_CALL XMACreateContext_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
XELOGD("XMACreateContext(%.8X)", context_out_ptr);
|
XELOGD("XMACreateContext(%.8X)", context_out_ptr);
|
||||||
|
|
||||||
auto xma_decoder = kernel_state->emulator()->xma_decoder();
|
auto xma_decoder = kernel_state->emulator()->audio_system()->xma_decoder();
|
||||||
uint32_t context_ptr = xma_decoder->AllocateContext();
|
uint32_t context_ptr = xma_decoder->AllocateContext();
|
||||||
SHIM_SET_MEM_32(context_out_ptr, context_ptr);
|
SHIM_SET_MEM_32(context_out_ptr, context_ptr);
|
||||||
if (!context_ptr) {
|
if (!context_ptr) {
|
||||||
|
@ -79,7 +79,7 @@ SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
XELOGD("XMAReleaseContext(%.8X)", context_ptr);
|
XELOGD("XMAReleaseContext(%.8X)", context_ptr);
|
||||||
|
|
||||||
auto xma_decoder = kernel_state->emulator()->xma_decoder();
|
auto xma_decoder = kernel_state->emulator()->audio_system()->xma_decoder();
|
||||||
xma_decoder->ReleaseContext(context_ptr);
|
xma_decoder->ReleaseContext(context_ptr);
|
||||||
|
|
||||||
SHIM_SET_RETURN_32(0);
|
SHIM_SET_RETURN_32(0);
|
||||||
|
@ -87,7 +87,7 @@ SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
void StoreXmaContextIndexedRegister(KernelState* kernel_state,
|
void StoreXmaContextIndexedRegister(KernelState* kernel_state,
|
||||||
uint32_t base_reg, uint32_t context_ptr) {
|
uint32_t base_reg, uint32_t context_ptr) {
|
||||||
auto xma_decoder = kernel_state->emulator()->xma_decoder();
|
auto xma_decoder = kernel_state->emulator()->audio_system()->xma_decoder();
|
||||||
uint32_t hw_index = (context_ptr - xma_decoder->context_array_ptr()) /
|
uint32_t hw_index = (context_ptr - xma_decoder->context_array_ptr()) /
|
||||||
sizeof(XMA_CONTEXT_DATA);
|
sizeof(XMA_CONTEXT_DATA);
|
||||||
uint32_t reg_num = base_reg + (hw_index >> 5) * 4;
|
uint32_t reg_num = base_reg + (hw_index >> 5) * 4;
|
||||||
|
@ -327,8 +327,8 @@ SHIM_CALL XMADisableContext_shim(PPCContext* ppc_context,
|
||||||
|
|
||||||
X_HRESULT result = X_E_SUCCESS;
|
X_HRESULT result = X_E_SUCCESS;
|
||||||
StoreXmaContextIndexedRegister(kernel_state, 0x1A40, context_ptr);
|
StoreXmaContextIndexedRegister(kernel_state, 0x1A40, context_ptr);
|
||||||
if (!kernel_state->emulator()->xma_decoder()->BlockOnContext(context_ptr,
|
if (!kernel_state->emulator()->audio_system()->xma_decoder()->BlockOnContext(
|
||||||
!wait)) {
|
context_ptr, !wait)) {
|
||||||
result = X_E_FALSE;
|
result = X_E_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue