Removing apu/ deps on Emulator.

This commit is contained in:
Ben Vanik 2015-08-18 10:54:56 -07:00
parent ad090a40eb
commit 19299fad4b
16 changed files with 93 additions and 124 deletions

View File

@ -9,15 +9,10 @@
#include "xenia/apu/audio_driver.h"
#include "xenia/emulator.h"
#include "xenia/cpu/processor.h"
#include "xenia/cpu/thread_state.h"
namespace xe {
namespace apu {
AudioDriver::AudioDriver(Emulator* emulator)
: emulator_(emulator), memory_(emulator->memory()) {}
AudioDriver::AudioDriver(Memory* memory) : memory_(memory) {}
AudioDriver::~AudioDriver() = default;

View File

@ -10,7 +10,7 @@
#ifndef XENIA_APU_AUDIO_DRIVER_H_
#define XENIA_APU_AUDIO_DRIVER_H_
#include "xenia/emulator.h"
#include "xenia/memory.h"
#include "xenia/xbox.h"
namespace xe {
@ -18,7 +18,7 @@ namespace apu {
class AudioDriver {
public:
explicit AudioDriver(Emulator* emulator);
explicit AudioDriver(Memory* memory);
virtual ~AudioDriver();
virtual void SubmitFrame(uint32_t samples_ptr) = 0;
@ -28,9 +28,7 @@ class AudioDriver {
return memory_->TranslatePhysical(guest_address);
}
Emulator* emulator_;
Memory* memory_;
cpu::Processor* processor_;
Memory* memory_ = nullptr;
};
} // namespace apu

View File

@ -11,15 +11,13 @@
#include "xenia/apu/apu_flags.h"
#include "xenia/apu/audio_driver.h"
#include "xenia/apu/xma_decoder.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
#include "xenia/base/ring_buffer.h"
#include "xenia/base/string_buffer.h"
#include "xenia/base/threading.h"
#include "xenia/cpu/processor.h"
#include "xenia/cpu/thread_state.h"
#include "xenia/emulator.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/profiling.h"
#include "xenia/apu/nop/nop_audio_system.h"
@ -42,31 +40,33 @@
namespace xe {
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) {
return nop::NopAudioSystem::Create(emulator);
return nop::NopAudioSystem::Create(processor);
#if XE_PLATFORM_WIN32
} else if (FLAGS_apu.compare("xaudio2") == 0) {
return xaudio2::XAudio2AudioSystem::Create(emulator);
return xaudio2::XAudio2AudioSystem::Create(processor);
#endif // WIN32
} else {
// Create best available.
std::unique_ptr<AudioSystem> best;
#if XE_PLATFORM_WIN32
best = xaudio2::XAudio2AudioSystem::Create(emulator);
best = xaudio2::XAudio2AudioSystem::Create(processor);
if (best) {
return best;
}
#endif // XE_PLATFORM_WIN32
// Fallback to nop.
return nop::NopAudioSystem::Create(emulator);
return nop::NopAudioSystem::Create(processor);
}
}
AudioSystem::AudioSystem(Emulator* emulator)
: emulator_(emulator), memory_(emulator->memory()), worker_running_(false) {
AudioSystem::AudioSystem(cpu::Processor* processor)
: memory_(processor->memory()),
processor_(processor),
worker_running_(false) {
std::memset(clients_, 0, sizeof(clients_));
for (size_t i = 0; i < kMaximumClientCount; ++i) {
unused_clients_.push(i);
@ -78,20 +78,28 @@ AudioSystem::AudioSystem(Emulator* emulator)
}
shutdown_event_ = xe::threading::Event::CreateManualResetEvent(false);
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() {
processor_ = emulator_->processor();
X_STATUS AudioSystem::Setup(kernel::KernelState* kernel_state) {
X_STATUS result = xma_decoder_->Setup(kernel_state);
if (result) {
return result;
}
worker_running_ = true;
worker_thread_ =
kernel::object_ref<kernel::XHostThread>(new kernel::XHostThread(
emulator()->kernel_state(), 128 * 1024, 0, [this]() {
WorkerThreadMain();
return 0;
}));
worker_thread_ = kernel::object_ref<kernel::XHostThread>(
new kernel::XHostThread(kernel_state, 128 * 1024, 0, [this]() {
WorkerThreadMain();
return 0;
}));
worker_thread_->set_name("Audio Worker");
worker_thread_->Create();
@ -102,8 +110,6 @@ void AudioSystem::WorkerThreadMain() {
// Initialize driver and ringbuffer.
Initialize();
auto processor = emulator_->processor();
// Main run loop.
while (worker_running_) {
auto result =
@ -126,8 +132,8 @@ void AudioSystem::WorkerThreadMain() {
if (client_callback) {
SCOPE_profile_cpu_i("apu", "xe::apu::AudioSystem->client_callback");
uint64_t args[] = {client_callback_arg};
processor->Execute(worker_thread_->thread_state(), client_callback,
args, xe::countof(args));
processor_->Execute(worker_thread_->thread_state(), client_callback,
args, xe::countof(args));
}
pumped++;
index++;

View File

@ -15,31 +15,28 @@
#include <queue>
#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"
namespace xe {
namespace kernel {
class XHostThread;
} // namespace kernel
} // namespace xe
namespace xe {
namespace apu {
class AudioDriver;
class XmaDecoder;
class AudioSystem {
public:
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_; }
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();
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);
protected:
explicit AudioSystem(Emulator* emulator);
explicit AudioSystem(cpu::Processor* processor);
virtual void Initialize();
@ -63,11 +60,11 @@ class AudioSystem {
// XAUDIO2_MAX_QUEUED_BUFFERS))
static const size_t kMaximumQueuedFrames = 64;
Emulator* emulator_;
Memory* memory_;
cpu::Processor* processor_;
Memory* memory_ = nullptr;
cpu::Processor* processor_ = nullptr;
std::unique_ptr<XmaDecoder> xma_decoder_;
std::atomic<bool> worker_running_;
std::atomic<bool> worker_running_ = {false};
kernel::object_ref<kernel::XHostThread> worker_thread_;
xe::mutex lock_;

View File

@ -15,11 +15,12 @@ namespace xe {
namespace apu {
namespace nop {
std::unique_ptr<AudioSystem> NopAudioSystem::Create(Emulator* emulator) {
return std::make_unique<NopAudioSystem>(emulator);
std::unique_ptr<AudioSystem> NopAudioSystem::Create(cpu::Processor* processor) {
return std::make_unique<NopAudioSystem>(processor);
}
NopAudioSystem::NopAudioSystem(Emulator* emulator) : AudioSystem(emulator) {}
NopAudioSystem::NopAudioSystem(cpu::Processor* processor)
: AudioSystem(processor) {}
NopAudioSystem::~NopAudioSystem() = default;

View File

@ -18,10 +18,10 @@ namespace nop {
class NopAudioSystem : public AudioSystem {
public:
explicit NopAudioSystem(Emulator* emulator);
explicit NopAudioSystem(cpu::Processor* processor);
~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,
AudioDriver** out_driver) override;

View File

@ -16,7 +16,6 @@
#include "xenia/apu/apu_flags.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
#include "xenia/emulator.h"
namespace xe {
namespace apu {
@ -43,9 +42,9 @@ class XAudio2AudioDriver::VoiceCallback : public IXAudio2VoiceCallback {
xe::threading::Semaphore* semaphore_ = nullptr;
};
XAudio2AudioDriver::XAudio2AudioDriver(Emulator* emulator,
XAudio2AudioDriver::XAudio2AudioDriver(Memory* memory,
xe::threading::Semaphore* semaphore)
: AudioDriver(emulator), semaphore_(semaphore) {
: AudioDriver(memory), semaphore_(semaphore) {
static_assert(frame_count_ == XAUDIO2_MAX_QUEUED_BUFFERS,
"xaudio header differs");
}

View File

@ -11,6 +11,7 @@
#define XENIA_APU_XAUDIO2_XAUDIO2_AUDIO_DRIVER_H_
#include "xenia/apu/audio_driver.h"
#include "xenia/base/threading.h"
struct IXAudio2;
struct IXAudio2MasteringVoice;
@ -22,7 +23,7 @@ namespace xaudio2 {
class XAudio2AudioDriver : public AudioDriver {
public:
XAudio2AudioDriver(Emulator* emulator, xe::threading::Semaphore* semaphore);
XAudio2AudioDriver(Memory* memory, xe::threading::Semaphore* semaphore);
~XAudio2AudioDriver() override;
void Initialize();

View File

@ -13,18 +13,18 @@
#include "xenia/apu/apu_flags.h"
#include "xenia/apu/xaudio2/xaudio2_audio_driver.h"
#include "xenia/emulator.h"
namespace xe {
namespace apu {
namespace xaudio2 {
std::unique_ptr<AudioSystem> XAudio2AudioSystem::Create(Emulator* emulator) {
return std::make_unique<XAudio2AudioSystem>(emulator);
std::unique_ptr<AudioSystem> XAudio2AudioSystem::Create(
cpu::Processor* processor) {
return std::make_unique<XAudio2AudioSystem>(processor);
}
XAudio2AudioSystem::XAudio2AudioSystem(Emulator* emulator)
: AudioSystem(emulator) {}
XAudio2AudioSystem::XAudio2AudioSystem(cpu::Processor* processor)
: AudioSystem(processor) {}
XAudio2AudioSystem::~XAudio2AudioSystem() {}
@ -34,7 +34,7 @@ X_STATUS XAudio2AudioSystem::CreateDriver(size_t index,
xe::threading::Semaphore* semaphore,
AudioDriver** out_driver) {
assert_not_null(out_driver);
auto driver = new XAudio2AudioDriver(emulator_, semaphore);
auto driver = new XAudio2AudioDriver(memory_, semaphore);
driver->Initialize();
*out_driver = driver;
return X_STATUS_SUCCESS;

View File

@ -18,10 +18,10 @@ namespace xaudio2 {
class XAudio2AudioSystem : public AudioSystem {
public:
explicit XAudio2AudioSystem(Emulator* emulator);
explicit XAudio2AudioSystem(cpu::Processor* processor);
~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,
AudioDriver** out_driver) override;

View File

@ -14,7 +14,7 @@
#include <mutex>
#include <queue>
#include "xenia/emulator.h"
#include "xenia/memory.h"
#include "xenia/xbox.h"
// XMA audio format:
@ -174,7 +174,7 @@ class XmaContext {
int DecodePacket(uint8_t* output, size_t offset, size_t size,
size_t* read_bytes);
Memory* memory_;
Memory* memory_ = nullptr;
uint32_t id_ = 0;
uint32_t guest_ptr_ = 0;

View File

@ -15,7 +15,6 @@
#include "xenia/base/string_buffer.h"
#include "xenia/cpu/processor.h"
#include "xenia/cpu/thread_state.h"
#include "xenia/emulator.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/profiling.h"
@ -50,15 +49,10 @@ extern "C" {
namespace xe {
namespace apu {
XmaDecoder::XmaDecoder(Emulator* emulator)
: emulator_(emulator),
memory_(emulator->memory()),
processor_(emulator->processor()),
worker_running_(false),
context_data_first_ptr_(0),
context_data_last_ptr_(0) {}
XmaDecoder::XmaDecoder(cpu::Processor* processor)
: memory_(processor->memory()), processor_(processor) {}
XmaDecoder::~XmaDecoder() {}
XmaDecoder::~XmaDecoder() = default;
void av_log_callback(void* avcl, int level, const char* fmt, va_list va) {
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());
}
X_STATUS XmaDecoder::Setup() {
X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) {
// Setup libav logging callback
av_log_set_callback(av_log_callback);
// Let the processor know we want register access callbacks.
emulator_->memory()->AddVirtualMappedRange(
memory_->AddVirtualMappedRange(
0x7FEA0000, 0xFFFF0000, 0x0000FFFF, this,
reinterpret_cast<cpu::MMIOReadCallback>(MMIOReadRegisterThunk),
reinterpret_cast<cpu::MMIOWriteCallback>(MMIOWriteRegisterThunk));
@ -95,12 +89,11 @@ X_STATUS XmaDecoder::Setup() {
registers_.next_context = 1;
worker_running_ = true;
worker_thread_ =
kernel::object_ref<kernel::XHostThread>(new kernel::XHostThread(
emulator()->kernel_state(), 128 * 1024, 0, [this]() {
WorkerThreadMain();
return 0;
}));
worker_thread_ = kernel::object_ref<kernel::XHostThread>(
new kernel::XHostThread(kernel_state, 128 * 1024, 0, [this]() {
WorkerThreadMain();
return 0;
}));
worker_thread_->set_name("XMA Decoder Worker");
worker_thread_->Create();

View File

@ -15,15 +15,9 @@
#include <queue>
#include "xenia/apu/xma_context.h"
#include "xenia/emulator.h"
#include "xenia/kernel/objects/xthread.h"
#include "xenia/xbox.h"
namespace xe {
namespace kernel {
class XHostThread;
} // namespace kernel
} // namespace xe
namespace xe {
namespace apu {
@ -31,15 +25,14 @@ struct XMA_CONTEXT_DATA;
class XmaDecoder {
public:
explicit XmaDecoder(Emulator* emulator);
explicit XmaDecoder(cpu::Processor* processor);
~XmaDecoder();
Emulator* emulator() const { return emulator_; }
Memory* memory() const { return memory_; }
cpu::Processor* processor() const { return processor_; }
virtual X_STATUS Setup();
virtual void Shutdown();
X_STATUS Setup(kernel::KernelState* kernel_state);
void Shutdown();
uint32_t context_array_ptr() const { return registers_.context_array_ptr; }
@ -47,8 +40,8 @@ class XmaDecoder {
void ReleaseContext(uint32_t guest_ptr);
bool BlockOnContext(uint32_t guest_ptr, bool poll);
virtual uint32_t ReadRegister(uint32_t addr);
virtual void WriteRegister(uint32_t addr, uint32_t value);
uint32_t ReadRegister(uint32_t addr);
void WriteRegister(uint32_t addr, uint32_t value);
protected:
int GetContextId(uint32_t guest_ptr);
@ -66,11 +59,10 @@ class XmaDecoder {
}
protected:
Emulator* emulator_;
Memory* memory_;
cpu::Processor* processor_;
Memory* memory_ = nullptr;
cpu::Processor* processor_ = nullptr;
std::atomic<bool> worker_running_;
std::atomic<bool> worker_running_ = {false};
kernel::object_ref<kernel::XHostThread> worker_thread_;
xe::threading::Fence worker_fence_;
@ -100,8 +92,8 @@ class XmaDecoder {
static const uint32_t kContextCount = 320;
XmaContext contexts_[kContextCount];
uint32_t context_data_first_ptr_;
uint32_t context_data_last_ptr_;
uint32_t context_data_first_ptr_ = 0;
uint32_t context_data_last_ptr_ = 0;
};
} // namespace apu

View File

@ -12,7 +12,6 @@
#include <gflags/gflags.h>
#include "xenia/apu/audio_system.h"
#include "xenia/apu/xma_decoder.h"
#include "xenia/base/assert.h"
#include "xenia/base/clock.h"
#include "xenia/base/logging.h"
@ -47,12 +46,10 @@ Emulator::~Emulator() {
// Give the systems time to shutdown before we delete them.
graphics_system_->Shutdown();
audio_system_->Shutdown();
xma_decoder_->Shutdown();
input_system_.reset();
graphics_system_.reset();
audio_system_.reset();
xma_decoder_.reset();
kernel_state_.reset();
file_system_.reset();
@ -104,13 +101,11 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
memory_.get(), export_resolver_.get(), debugger_.get());
// Initialize the APU.
audio_system_ = xe::apu::AudioSystem::Create(this);
audio_system_ = xe::apu::AudioSystem::Create(processor_.get());
if (!audio_system_) {
return X_STATUS_NOT_IMPLEMENTED;
}
xma_decoder_ = std::make_unique<xe::apu::XmaDecoder>(this);
// Initialize the GPU.
graphics_system_ = xe::gpu::GraphicsSystem::Create(this);
if (!graphics_system_) {
@ -148,12 +143,7 @@ X_STATUS Emulator::Setup(ui::Window* display_window) {
return result;
}
result = audio_system_->Setup();
if (result) {
return result;
}
result = xma_decoder_->Setup();
result = audio_system_->Setup(kernel_state_.get());
if (result) {
return result;
}

View File

@ -21,7 +21,6 @@
namespace xe {
namespace apu {
class AudioSystem;
class XmaDecoder;
} // namespace apu
namespace cpu {
class ExportResolver;
@ -56,7 +55,6 @@ class Emulator {
cpu::Processor* processor() const { return processor_.get(); }
apu::AudioSystem* audio_system() const { return audio_system_.get(); }
apu::XmaDecoder* xma_decoder() const { return xma_decoder_.get(); }
gpu::GraphicsSystem* graphics_system() const {
return graphics_system_.get();
}
@ -90,7 +88,6 @@ class Emulator {
std::unique_ptr<cpu::Processor> processor_;
std::unique_ptr<apu::AudioSystem> audio_system_;
std::unique_ptr<apu::XmaDecoder> xma_decoder_;
std::unique_ptr<gpu::GraphicsSystem> graphics_system_;
std::unique_ptr<hid::InputSystem> input_system_;

View File

@ -62,7 +62,7 @@ SHIM_CALL XMACreateContext_shim(PPCContext* ppc_context,
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();
SHIM_SET_MEM_32(context_out_ptr, context_ptr);
if (!context_ptr) {
@ -79,7 +79,7 @@ SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_context,
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);
SHIM_SET_RETURN_32(0);
@ -87,7 +87,7 @@ SHIM_CALL XMAReleaseContext_shim(PPCContext* ppc_context,
void StoreXmaContextIndexedRegister(KernelState* kernel_state,
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()) /
sizeof(XMA_CONTEXT_DATA);
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;
StoreXmaContextIndexedRegister(kernel_state, 0x1A40, context_ptr);
if (!kernel_state->emulator()->xma_decoder()->BlockOnContext(context_ptr,
!wait)) {
if (!kernel_state->emulator()->audio_system()->xma_decoder()->BlockOnContext(
context_ptr, !wait)) {
result = X_E_FALSE;
}