[APU] Added new XMA decoder as config option.

This commit is contained in:
Gliniak
2024-03-25 21:59:49 +01:00
committed by Radosław Gliński
parent 26ea81624a
commit 122f58c9dd
9 changed files with 1976 additions and 996 deletions

View File

@@ -10,6 +10,9 @@
#include "xenia/apu/xma_decoder.h"
#include "xenia/apu/xma_context.h"
#include "xenia/apu/xma_context_new.h"
#include "xenia/apu/xma_context_old.h"
#include "xenia/base/cvar.h"
#include "xenia/base/logging.h"
#include "xenia/base/math.h"
@@ -51,6 +54,14 @@ extern "C" {
DEFINE_bool(ffmpeg_verbose, false, "Verbose FFmpeg output (debug and above)",
"APU");
DEFINE_bool(use_new_decoder, false,
"Enables usage of new experimental XMA audio decoder.", "APU");
DEFINE_bool(use_dedicated_xma_thread, true,
"Enables XMA decoding on separate thread. Disabled should produce "
"better results, but decrease performance a bit.",
"APU");
namespace xe {
namespace apu {
@@ -128,9 +139,14 @@ X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) {
// Setup XMA contexts.
for (int i = 0; i < kContextCount; ++i) {
if (cvars::use_new_decoder) {
contexts_[i] = new XmaContextNew();
} else {
contexts_[i] = new XmaContextOld();
}
uint32_t guest_ptr = context_data_first_ptr_ + i * sizeof(XMA_CONTEXT_DATA);
XmaContext& context = contexts_[i];
if (context.Setup(i, memory(), guest_ptr)) {
if (contexts_[i]->Setup(i, memory(), guest_ptr)) {
assert_always();
}
}
@@ -144,7 +160,9 @@ X_STATUS XmaDecoder::Setup(kernel::KernelState* kernel_state) {
kernel::object_ref<kernel::XHostThread>(new kernel::XHostThread(
kernel_state, 128 * 1024, 0,
[this]() {
WorkerThreadMain();
if (cvars::use_dedicated_xma_thread) {
WorkerThreadMain();
}
return 0;
},
kernel_state
@@ -163,8 +181,7 @@ void XmaDecoder::WorkerThreadMain() {
// Okay, let's loop through XMA contexts to find ones we need to decode!
bool did_work = false;
for (uint32_t n = 0; n < kContextCount; n++) {
XmaContext& context = contexts_[n];
did_work = context.Work() || did_work;
did_work = contexts_[n]->Work() || did_work;
// TODO: Need thread safety to do this.
// Probably not too important though.
@@ -228,7 +245,7 @@ uint32_t XmaDecoder::AllocateContext() {
return 0;
}
XmaContext& context = contexts_[index];
XmaContext& context = *contexts_[index];
assert_false(context.is_allocated());
context.set_is_allocated(true);
return context.guest_ptr();
@@ -238,7 +255,7 @@ void XmaDecoder::ReleaseContext(uint32_t guest_ptr) {
auto context_id = GetContextId(guest_ptr);
assert_true(context_id >= 0);
XmaContext& context = contexts_[context_id];
XmaContext& context = *contexts_[context_id];
assert_true(context.is_allocated());
context.Release();
context_bitmap_.Release(context_id);
@@ -248,7 +265,7 @@ bool XmaDecoder::BlockOnContext(uint32_t guest_ptr, bool poll) {
auto context_id = GetContextId(guest_ptr);
assert_true(context_id >= 0);
XmaContext& context = contexts_[context_id];
XmaContext& context = *contexts_[context_id];
return context.Block(poll);
}
@@ -309,8 +326,11 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) {
for (int i = 0; value && i < 32; ++i, value >>= 1) {
if (value & 1) {
uint32_t context_id = base_context_id + i;
auto& context = contexts_[context_id];
auto& context = *contexts_[context_id];
context.Enable();
if (!cvars::use_dedicated_xma_thread) {
context.Work();
}
}
}
// Signal the decoder thread to start processing.
@@ -323,7 +343,7 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) {
for (int i = 0; value && i < 32; ++i, value >>= 1) {
if (value & 1) {
uint32_t context_id = base_context_id + i;
auto& context = contexts_[context_id];
auto& context = *contexts_[context_id];
context.Disable();
}
}
@@ -337,7 +357,7 @@ void XmaDecoder::WriteRegister(uint32_t addr, uint32_t value) {
for (int i = 0; value && i < 32; ++i, value >>= 1) {
if (value & 1) {
uint32_t context_id = base_context_id + i;
XmaContext& context = contexts_[context_id];
XmaContext& context = *contexts_[context_id];
context.Clear();
}
}