mirror of
https://github.com/yuzu-emu/yuzu.git
synced 2025-06-20 13:07:53 -05:00
Project Andio
This commit is contained in:
125
src/audio_core/renderer/memory/address_info.h
Normal file
125
src/audio_core/renderer/memory/address_info.h
Normal file
@ -0,0 +1,125 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "audio_core/renderer/memory/memory_pool_info.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace AudioCore::AudioRenderer {
|
||||
|
||||
/**
|
||||
* Represents a region of mapped or unmapped memory.
|
||||
*/
|
||||
class AddressInfo {
|
||||
public:
|
||||
AddressInfo() = default;
|
||||
AddressInfo(CpuAddr cpu_address_, u64 size_) : cpu_address{cpu_address_}, size{size_} {}
|
||||
|
||||
/**
|
||||
* Setup a new AddressInfo.
|
||||
*
|
||||
* @param cpu_address - The CPU address of this region.
|
||||
* @param size - The size of this region.
|
||||
*/
|
||||
void Setup(CpuAddr cpu_address_, u64 size_) {
|
||||
cpu_address = cpu_address_;
|
||||
size = size_;
|
||||
memory_pool = nullptr;
|
||||
dsp_address = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CPU address.
|
||||
*
|
||||
* @return The CpuAddr address
|
||||
*/
|
||||
CpuAddr GetCpuAddr() const {
|
||||
return cpu_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign this region to a memory pool.
|
||||
*
|
||||
* @param memory_pool_ - Memory pool to assign.
|
||||
* @return The CpuAddr address of this region.
|
||||
*/
|
||||
void SetPool(MemoryPoolInfo* memory_pool_) {
|
||||
memory_pool = memory_pool_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of this region.
|
||||
*
|
||||
* @return The size of this region.
|
||||
*/
|
||||
u64 GetSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ADSP address for this region.
|
||||
*
|
||||
* @return The ADSP address for this region.
|
||||
*/
|
||||
CpuAddr GetForceMappedDspAddr() const {
|
||||
return dsp_address;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the ADSP address for this region.
|
||||
*
|
||||
* @param dsp_addr - The new ADSP address for this region.
|
||||
*/
|
||||
void SetForceMappedDspAddr(CpuAddr dsp_addr) {
|
||||
dsp_address = dsp_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this region has an active memory pool.
|
||||
*
|
||||
* @return True if this region has a mapped memory pool, otherwise false.
|
||||
*/
|
||||
bool HasMappedMemoryPool() const {
|
||||
return memory_pool != nullptr && memory_pool->GetDspAddress() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this region is mapped to the ADSP.
|
||||
*
|
||||
* @return True if this region is mapped, otherwise false.
|
||||
*/
|
||||
bool IsMapped() const {
|
||||
return HasMappedMemoryPool() || dsp_address != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a usable reference to this region of memory.
|
||||
*
|
||||
* @param mark_in_use - Whether this region should be marked as being in use.
|
||||
* @return A valid memory address if valid, otherwise 0.
|
||||
*/
|
||||
CpuAddr GetReference(bool mark_in_use) {
|
||||
if (!HasMappedMemoryPool()) {
|
||||
return dsp_address;
|
||||
}
|
||||
|
||||
if (mark_in_use) {
|
||||
memory_pool->SetUsed(true);
|
||||
}
|
||||
|
||||
return memory_pool->Translate(cpu_address, size);
|
||||
}
|
||||
|
||||
private:
|
||||
/// CPU address of this region
|
||||
CpuAddr cpu_address;
|
||||
/// Size of this region
|
||||
u64 size;
|
||||
/// The memory this region is mapped to
|
||||
MemoryPoolInfo* memory_pool;
|
||||
/// ADSP address of this region
|
||||
CpuAddr dsp_address;
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioRenderer
|
61
src/audio_core/renderer/memory/memory_pool_info.cpp
Normal file
61
src/audio_core/renderer/memory/memory_pool_info.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio_core/renderer/memory/memory_pool_info.h"
|
||||
|
||||
namespace AudioCore::AudioRenderer {
|
||||
|
||||
CpuAddr MemoryPoolInfo::GetCpuAddress() const {
|
||||
return cpu_address;
|
||||
}
|
||||
|
||||
CpuAddr MemoryPoolInfo::GetDspAddress() const {
|
||||
return dsp_address;
|
||||
}
|
||||
|
||||
u64 MemoryPoolInfo::GetSize() const {
|
||||
return size;
|
||||
}
|
||||
|
||||
MemoryPoolInfo::Location MemoryPoolInfo::GetLocation() const {
|
||||
return location;
|
||||
}
|
||||
|
||||
void MemoryPoolInfo::SetCpuAddress(const CpuAddr address, const u64 size_) {
|
||||
cpu_address = address;
|
||||
size = size_;
|
||||
}
|
||||
|
||||
void MemoryPoolInfo::SetDspAddress(const CpuAddr address) {
|
||||
dsp_address = address;
|
||||
}
|
||||
|
||||
bool MemoryPoolInfo::Contains(const CpuAddr address_, const u64 size_) const {
|
||||
return cpu_address <= address_ && (address_ + size_) <= (cpu_address + size);
|
||||
}
|
||||
|
||||
bool MemoryPoolInfo::IsMapped() const {
|
||||
return dsp_address != 0;
|
||||
}
|
||||
|
||||
CpuAddr MemoryPoolInfo::Translate(const CpuAddr address, const u64 size_) const {
|
||||
if (!Contains(address, size_)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!IsMapped()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dsp_address + (address - cpu_address);
|
||||
}
|
||||
|
||||
void MemoryPoolInfo::SetUsed(const bool used) {
|
||||
in_use = used;
|
||||
}
|
||||
|
||||
bool MemoryPoolInfo::IsUsed() const {
|
||||
return in_use;
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioRenderer
|
170
src/audio_core/renderer/memory/memory_pool_info.h
Normal file
170
src/audio_core/renderer/memory/memory_pool_info.h
Normal file
@ -0,0 +1,170 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "audio_core/common/common.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace AudioCore::AudioRenderer {
|
||||
/**
|
||||
* CPU pools are mapped in user memory with the supplied process_handle (see PoolMapper).
|
||||
*/
|
||||
class MemoryPoolInfo {
|
||||
public:
|
||||
/**
|
||||
* The location of this pool.
|
||||
* CPU pools are mapped in user memory with the supplied process_handle (see PoolMapper).
|
||||
* DSP pools are mapped in the current process sysmodule.
|
||||
*/
|
||||
enum class Location {
|
||||
CPU = 1,
|
||||
DSP = 2,
|
||||
};
|
||||
|
||||
/**
|
||||
* Current state of the pool
|
||||
*/
|
||||
enum class State {
|
||||
Invalid,
|
||||
Aquired,
|
||||
RequestDetach,
|
||||
Detached,
|
||||
RequestAttach,
|
||||
Attached,
|
||||
Released,
|
||||
};
|
||||
|
||||
/**
|
||||
* Result code for updating the pool (See InfoUpdater::Update)
|
||||
*/
|
||||
enum class ResultState {
|
||||
Success,
|
||||
BadParam,
|
||||
MapFailed,
|
||||
InUse,
|
||||
};
|
||||
|
||||
/**
|
||||
* Input parameters coming from the game which are used to update current pools
|
||||
* (See InfoUpdater::Update)
|
||||
*/
|
||||
struct InParameter {
|
||||
/* 0x00 */ u64 address;
|
||||
/* 0x08 */ u64 size;
|
||||
/* 0x10 */ State state;
|
||||
/* 0x14 */ bool in_use;
|
||||
/* 0x18 */ char unk18[0x8];
|
||||
};
|
||||
static_assert(sizeof(InParameter) == 0x20, "MemoryPoolInfo::InParameter has the wrong size!");
|
||||
|
||||
/**
|
||||
* Output status sent back to the game on update (See InfoUpdater::Update)
|
||||
*/
|
||||
struct OutStatus {
|
||||
/* 0x00 */ State state;
|
||||
/* 0x04 */ char unk04[0xC];
|
||||
};
|
||||
static_assert(sizeof(OutStatus) == 0x10, "MemoryPoolInfo::OutStatus has the wrong size!");
|
||||
|
||||
MemoryPoolInfo() = default;
|
||||
MemoryPoolInfo(Location location_) : location{location_} {}
|
||||
|
||||
/**
|
||||
* Get the CPU address for this pool.
|
||||
*
|
||||
* @return The CPU address of this pool.
|
||||
*/
|
||||
CpuAddr GetCpuAddress() const;
|
||||
|
||||
/**
|
||||
* Get the DSP address for this pool.
|
||||
*
|
||||
* @return The DSP address of this pool.
|
||||
*/
|
||||
CpuAddr GetDspAddress() const;
|
||||
|
||||
/**
|
||||
* Get the size of this pool.
|
||||
*
|
||||
* @return The size of this pool.
|
||||
*/
|
||||
u64 GetSize() const;
|
||||
|
||||
/**
|
||||
* Get the location of this pool.
|
||||
*
|
||||
* @return The location for the pool (see MemoryPoolInfo::Location).
|
||||
*/
|
||||
Location GetLocation() const;
|
||||
|
||||
/**
|
||||
* Set the CPU address for this pool.
|
||||
*
|
||||
* @param address - The new CPU address for this pool.
|
||||
* @param size - The new size for this pool.
|
||||
*/
|
||||
void SetCpuAddress(CpuAddr address, u64 size);
|
||||
|
||||
/**
|
||||
* Set the DSP address for this pool.
|
||||
*
|
||||
* @param address - The new DSP address for this pool.
|
||||
*/
|
||||
void SetDspAddress(CpuAddr address);
|
||||
|
||||
/**
|
||||
* Check whether the pool contains a given range.
|
||||
*
|
||||
* @param address - The buffer address to look for.
|
||||
* @param size - The size of the given buffer.
|
||||
* @return True if the range is within this pool, otherwise false.
|
||||
*/
|
||||
bool Contains(CpuAddr address, u64 size) const;
|
||||
|
||||
/**
|
||||
* Check whether this pool is mapped, which is when the dsp address is set.
|
||||
*
|
||||
* @return True if the pool is mapped, otherwise false.
|
||||
*/
|
||||
bool IsMapped() const;
|
||||
|
||||
/**
|
||||
* Translates a given CPU range into a relative offset for the DSP.
|
||||
*
|
||||
* @param address - The buffer address to look for.
|
||||
* @param size - The size of the given buffer.
|
||||
* @return Pointer to the DSP-mapped memory.
|
||||
*/
|
||||
CpuAddr Translate(CpuAddr address, u64 size) const;
|
||||
|
||||
/**
|
||||
* Set or unset whether this memory pool is in use.
|
||||
*
|
||||
* @param used - Use state for this pool.
|
||||
*/
|
||||
void SetUsed(bool used);
|
||||
|
||||
/**
|
||||
* Get whether this pool is in use.
|
||||
*
|
||||
* @return True if in use, otherwise false.
|
||||
*/
|
||||
bool IsUsed() const;
|
||||
|
||||
private:
|
||||
/// Base address for the CPU-side memory
|
||||
CpuAddr cpu_address{};
|
||||
/// Base address for the DSP-side memory
|
||||
CpuAddr dsp_address{};
|
||||
/// Size of this pool
|
||||
u64 size{};
|
||||
/// Location of this pool, either CPU or DSP
|
||||
Location location{Location::DSP};
|
||||
/// If this pool is in use
|
||||
bool in_use{};
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioRenderer
|
243
src/audio_core/renderer/memory/pool_mapper.cpp
Normal file
243
src/audio_core/renderer/memory/pool_mapper.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio_core/renderer/memory/address_info.h"
|
||||
#include "audio_core/renderer/memory/pool_mapper.h"
|
||||
#include "core/hle/kernel/k_process.h"
|
||||
#include "core/hle/kernel/svc.h"
|
||||
|
||||
namespace AudioCore::AudioRenderer {
|
||||
|
||||
PoolMapper::PoolMapper(u32 process_handle_, bool force_map_)
|
||||
: process_handle{process_handle_}, force_map{force_map_} {}
|
||||
|
||||
PoolMapper::PoolMapper(u32 process_handle_, std::span<MemoryPoolInfo> pool_infos_, u32 pool_count_,
|
||||
bool force_map_)
|
||||
: process_handle{process_handle_}, pool_infos{pool_infos_.data()},
|
||||
pool_count{pool_count_}, force_map{force_map_} {}
|
||||
|
||||
void PoolMapper::ClearUseState(std::span<MemoryPoolInfo> pools, const u32 count) {
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
pools[i].SetUsed(false);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPoolInfo* PoolMapper::FindMemoryPool(MemoryPoolInfo* pools, const u64 count,
|
||||
const CpuAddr address, const u64 size) const {
|
||||
auto pool{pools};
|
||||
for (u64 i = 0; i < count; i++, pool++) {
|
||||
if (pool->Contains(address, size)) {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MemoryPoolInfo* PoolMapper::FindMemoryPool(const CpuAddr address, const u64 size) const {
|
||||
auto pool{pool_infos};
|
||||
for (u64 i = 0; i < pool_count; i++, pool++) {
|
||||
if (pool->Contains(address, size)) {
|
||||
return pool;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PoolMapper::FillDspAddr(AddressInfo& address_info, MemoryPoolInfo* pools,
|
||||
const u32 count) const {
|
||||
if (address_info.GetCpuAddr() == 0) {
|
||||
address_info.SetPool(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto found_pool{
|
||||
FindMemoryPool(pools, count, address_info.GetCpuAddr(), address_info.GetSize())};
|
||||
if (found_pool != nullptr) {
|
||||
address_info.SetPool(found_pool);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (force_map) {
|
||||
address_info.SetForceMappedDspAddr(address_info.GetCpuAddr());
|
||||
} else {
|
||||
address_info.SetPool(nullptr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PoolMapper::FillDspAddr(AddressInfo& address_info) const {
|
||||
if (address_info.GetCpuAddr() == 0) {
|
||||
address_info.SetPool(nullptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto found_pool{FindMemoryPool(address_info.GetCpuAddr(), address_info.GetSize())};
|
||||
if (found_pool != nullptr) {
|
||||
address_info.SetPool(found_pool);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (force_map) {
|
||||
address_info.SetForceMappedDspAddr(address_info.GetCpuAddr());
|
||||
} else {
|
||||
address_info.SetPool(nullptr);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PoolMapper::TryAttachBuffer(BehaviorInfo::ErrorInfo& error_info, AddressInfo& address_info,
|
||||
const CpuAddr address, const u64 size) const {
|
||||
address_info.Setup(address, size);
|
||||
|
||||
if (!FillDspAddr(address_info)) {
|
||||
error_info.error_code = Service::Audio::ERR_POOL_MAPPING_FAILED;
|
||||
error_info.address = address;
|
||||
return force_map;
|
||||
}
|
||||
|
||||
error_info.error_code = ResultSuccess;
|
||||
error_info.address = CpuAddr(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PoolMapper::IsForceMapEnabled() const {
|
||||
return force_map;
|
||||
}
|
||||
|
||||
u32 PoolMapper::GetProcessHandle(const MemoryPoolInfo* pool) const {
|
||||
switch (pool->GetLocation()) {
|
||||
case MemoryPoolInfo::Location::CPU:
|
||||
return process_handle;
|
||||
case MemoryPoolInfo::Location::DSP:
|
||||
return Kernel::Svc::CurrentProcess;
|
||||
}
|
||||
LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location!");
|
||||
return Kernel::Svc::CurrentProcess;
|
||||
}
|
||||
|
||||
bool PoolMapper::Map([[maybe_unused]] const u32 handle, [[maybe_unused]] const CpuAddr cpu_addr,
|
||||
[[maybe_unused]] const u64 size) const {
|
||||
// nn::audio::dsp::MapUserPointer(handle, cpu_addr, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PoolMapper::Map(MemoryPoolInfo& pool) const {
|
||||
switch (pool.GetLocation()) {
|
||||
case MemoryPoolInfo::Location::CPU:
|
||||
// Map with process_handle
|
||||
pool.SetDspAddress(pool.GetCpuAddress());
|
||||
return true;
|
||||
case MemoryPoolInfo::Location::DSP:
|
||||
// Map with Kernel::Svc::CurrentProcess
|
||||
pool.SetDspAddress(pool.GetCpuAddress());
|
||||
return true;
|
||||
default:
|
||||
LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location={}!",
|
||||
static_cast<u32>(pool.GetLocation()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool PoolMapper::Unmap([[maybe_unused]] const u32 handle, [[maybe_unused]] const CpuAddr cpu_addr,
|
||||
[[maybe_unused]] const u64 size) const {
|
||||
// nn::audio::dsp::UnmapUserPointer(handle, cpu_addr, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PoolMapper::Unmap(MemoryPoolInfo& pool) const {
|
||||
[[maybe_unused]] u32 handle{0};
|
||||
|
||||
switch (pool.GetLocation()) {
|
||||
case MemoryPoolInfo::Location::CPU:
|
||||
handle = process_handle;
|
||||
break;
|
||||
case MemoryPoolInfo::Location::DSP:
|
||||
handle = Kernel::Svc::CurrentProcess;
|
||||
break;
|
||||
}
|
||||
// nn::audio::dsp::UnmapUserPointer(handle, pool->cpu_address, pool->size);
|
||||
pool.SetCpuAddress(0, 0);
|
||||
pool.SetDspAddress(0);
|
||||
return true;
|
||||
}
|
||||
|
||||
void PoolMapper::ForceUnmapPointer(const AddressInfo& address_info) const {
|
||||
if (force_map) {
|
||||
[[maybe_unused]] auto found_pool{
|
||||
FindMemoryPool(address_info.GetCpuAddr(), address_info.GetSize())};
|
||||
// nn::audio::dsp::UnmapUserPointer(this->processHandle, address_info.GetCpuAddr(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
MemoryPoolInfo::ResultState PoolMapper::Update(MemoryPoolInfo& pool,
|
||||
const MemoryPoolInfo::InParameter& in_params,
|
||||
MemoryPoolInfo::OutStatus& out_params) const {
|
||||
if (in_params.state != MemoryPoolInfo::State::RequestAttach &&
|
||||
in_params.state != MemoryPoolInfo::State::RequestDetach) {
|
||||
return MemoryPoolInfo::ResultState::Success;
|
||||
}
|
||||
|
||||
if (in_params.address == 0 || in_params.size == 0 || !Common::Is4KBAligned(in_params.address) ||
|
||||
!Common::Is4KBAligned(in_params.size)) {
|
||||
return MemoryPoolInfo::ResultState::BadParam;
|
||||
}
|
||||
|
||||
switch (in_params.state) {
|
||||
case MemoryPoolInfo::State::RequestAttach:
|
||||
pool.SetCpuAddress(in_params.address, in_params.size);
|
||||
|
||||
Map(pool);
|
||||
|
||||
if (pool.IsMapped()) {
|
||||
out_params.state = MemoryPoolInfo::State::Attached;
|
||||
return MemoryPoolInfo::ResultState::Success;
|
||||
}
|
||||
pool.SetCpuAddress(0, 0);
|
||||
return MemoryPoolInfo::ResultState::MapFailed;
|
||||
|
||||
case MemoryPoolInfo::State::RequestDetach:
|
||||
if (pool.GetCpuAddress() != in_params.address || pool.GetSize() != in_params.size) {
|
||||
return MemoryPoolInfo::ResultState::BadParam;
|
||||
}
|
||||
|
||||
if (pool.IsUsed()) {
|
||||
return MemoryPoolInfo::ResultState::InUse;
|
||||
}
|
||||
|
||||
Unmap(pool);
|
||||
|
||||
pool.SetCpuAddress(0, 0);
|
||||
pool.SetDspAddress(0);
|
||||
out_params.state = MemoryPoolInfo::State::Detached;
|
||||
return MemoryPoolInfo::ResultState::Success;
|
||||
|
||||
default:
|
||||
LOG_ERROR(Service_Audio, "Invalid MemoryPoolInfo::State!");
|
||||
break;
|
||||
}
|
||||
|
||||
return MemoryPoolInfo::ResultState::Success;
|
||||
}
|
||||
|
||||
bool PoolMapper::InitializeSystemPool(MemoryPoolInfo& pool, const u8* memory,
|
||||
const u64 size_) const {
|
||||
switch (pool.GetLocation()) {
|
||||
case MemoryPoolInfo::Location::CPU:
|
||||
return false;
|
||||
case MemoryPoolInfo::Location::DSP:
|
||||
pool.SetCpuAddress(reinterpret_cast<u64>(memory), size_);
|
||||
if (Map(Kernel::Svc::CurrentProcess, reinterpret_cast<u64>(memory), size_)) {
|
||||
pool.SetDspAddress(pool.GetCpuAddress());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
default:
|
||||
LOG_WARNING(Service_Audio, "Invalid MemoryPoolInfo location={}!",
|
||||
static_cast<u32>(pool.GetLocation()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace AudioCore::AudioRenderer
|
179
src/audio_core/renderer/memory/pool_mapper.h
Normal file
179
src/audio_core/renderer/memory/pool_mapper.h
Normal file
@ -0,0 +1,179 @@
|
||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <span>
|
||||
|
||||
#include "audio_core/renderer/behavior/behavior_info.h"
|
||||
#include "audio_core/renderer/memory/memory_pool_info.h"
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/service/audio/errors.h"
|
||||
|
||||
namespace AudioCore::AudioRenderer {
|
||||
class AddressInfo;
|
||||
|
||||
/**
|
||||
* Utility functions for managing MemoryPoolInfos
|
||||
*/
|
||||
class PoolMapper {
|
||||
public:
|
||||
explicit PoolMapper(u32 process_handle, bool force_map);
|
||||
explicit PoolMapper(u32 process_handle, std::span<MemoryPoolInfo> pool_infos, u32 pool_count,
|
||||
bool force_map);
|
||||
|
||||
/**
|
||||
* Clear the usage state for all given pools.
|
||||
*
|
||||
* @param pools - The memory pools to clear.
|
||||
* @param count - The number of pools.
|
||||
*/
|
||||
static void ClearUseState(std::span<MemoryPoolInfo> pools, u32 count);
|
||||
|
||||
/**
|
||||
* Find the memory pool containing the given address and size from a given list of pools.
|
||||
*
|
||||
* @param pools - The memory pools to search within.
|
||||
* @param count - The number of pools.
|
||||
* @param address - The address of the region to find.
|
||||
* @param size - The size of the region to find.
|
||||
* @return Pointer to the memory pool if found, otherwise nullptr.
|
||||
*/
|
||||
MemoryPoolInfo* FindMemoryPool(MemoryPoolInfo* pools, u64 count, CpuAddr address,
|
||||
u64 size) const;
|
||||
|
||||
/**
|
||||
* Find the memory pool containing the given address and size from the PoolMapper's memory pool.
|
||||
*
|
||||
* @param address - The address of the region to find.
|
||||
* @param size - The size of the region to find.
|
||||
* @return Pointer to the memory pool if found, otherwise nullptr.
|
||||
*/
|
||||
MemoryPoolInfo* FindMemoryPool(CpuAddr address, u64 size) const;
|
||||
|
||||
/**
|
||||
* Set the PoolMapper's memory pool to one in the given list of pools, which contains
|
||||
* address_info.
|
||||
*
|
||||
* @param address_info - The expected region to find within pools.
|
||||
* @param pools - The list of pools to search within.
|
||||
* @param count - The number of pools given.
|
||||
* @return True if successfully mapped, otherwise false.
|
||||
*/
|
||||
bool FillDspAddr(AddressInfo& address_info, MemoryPoolInfo* pools, u32 count) const;
|
||||
|
||||
/**
|
||||
* Set the PoolMapper's memory pool to the one containing address_info.
|
||||
*
|
||||
* @param address_info - The address to find the memory pool for.
|
||||
* @return True if successfully mapped, otherwise false.
|
||||
*/
|
||||
bool FillDspAddr(AddressInfo& address_info) const;
|
||||
|
||||
/**
|
||||
* Try to attach a {address, size} region to the given address_info, and map it. Fills in the
|
||||
* given error_info and address_info.
|
||||
*
|
||||
* @param error_info - Output error info.
|
||||
* @param address_info - Output address info, initialized with the given {address, size} and
|
||||
* attempted to map.
|
||||
* @param address - Address of the region to map.
|
||||
* @param size - Size of the region to map.
|
||||
* @return True if successfully attached, otherwise false.
|
||||
*/
|
||||
bool TryAttachBuffer(BehaviorInfo::ErrorInfo& error_info, AddressInfo& address_info,
|
||||
CpuAddr address, u64 size) const;
|
||||
|
||||
/**
|
||||
* Return whether force mapping is enabled.
|
||||
*
|
||||
* @return True if force mapping is enabled, otherwise false.
|
||||
*/
|
||||
bool IsForceMapEnabled() const;
|
||||
|
||||
/**
|
||||
* Get the process handle, depending on location.
|
||||
*
|
||||
* @param pool - The pool to check the location of.
|
||||
* @return CurrentProcessHandle if location == DSP,
|
||||
* the PoolMapper's process_handle if location == CPU
|
||||
*/
|
||||
u32 GetProcessHandle(const MemoryPoolInfo* pool) const;
|
||||
|
||||
/**
|
||||
* Map the given region with the given handle. This is a no-op.
|
||||
*
|
||||
* @param handle - The process handle to map to.
|
||||
* @param cpu_addr - Address to map.
|
||||
* @param size - Size to map.
|
||||
* @return True if successfully mapped, otherwise false.
|
||||
*/
|
||||
bool Map(u32 handle, CpuAddr cpu_addr, u64 size) const;
|
||||
|
||||
/**
|
||||
* Map the given memory pool.
|
||||
*
|
||||
* @param pool - The pool to map.
|
||||
* @return True if successfully mapped, otherwise false.
|
||||
*/
|
||||
bool Map(MemoryPoolInfo& pool) const;
|
||||
|
||||
/**
|
||||
* Unmap the given region with the given handle.
|
||||
*
|
||||
* @param handle - The process handle to unmap to.
|
||||
* @param cpu_addr - Address to unmap.
|
||||
* @param size - Size to unmap.
|
||||
* @return True if successfully unmapped, otherwise false.
|
||||
*/
|
||||
bool Unmap(u32 handle, CpuAddr cpu_addr, u64 size) const;
|
||||
|
||||
/**
|
||||
* Unmap the given memory pool.
|
||||
*
|
||||
* @param pool - The pool to unmap.
|
||||
* @return True if successfully unmapped, otherwise false.
|
||||
*/
|
||||
bool Unmap(MemoryPoolInfo& pool) const;
|
||||
|
||||
/**
|
||||
* Forcibly unmap the given region.
|
||||
*
|
||||
* @param address_info - The region to unmap.
|
||||
*/
|
||||
void ForceUnmapPointer(const AddressInfo& address_info) const;
|
||||
|
||||
/**
|
||||
* Update the given memory pool.
|
||||
*
|
||||
* @param pool - Pool to update.
|
||||
* @param in_params - Input parameters for the update.
|
||||
* @param out_params - Output parameters for the update.
|
||||
* @return The result of the update. See MemoryPoolInfo::ResultState
|
||||
*/
|
||||
MemoryPoolInfo::ResultState Update(MemoryPoolInfo& pool,
|
||||
const MemoryPoolInfo::InParameter& in_params,
|
||||
MemoryPoolInfo::OutStatus& out_params) const;
|
||||
|
||||
/**
|
||||
* Initialize the PoolMapper's memory pool.
|
||||
*
|
||||
* @param pool - Input pool to initialize.
|
||||
* @param memory - Pointer to the memory region for the pool.
|
||||
* @param size - Size of the memory region for the pool.
|
||||
* @return True if initialized successfully, otherwise false.
|
||||
*/
|
||||
bool InitializeSystemPool(MemoryPoolInfo& pool, const u8* memory, u64 size) const;
|
||||
|
||||
private:
|
||||
/// Process handle for this mapper, used when location == CPU
|
||||
u32 process_handle;
|
||||
/// List of memory pools assigned to this mapper
|
||||
MemoryPoolInfo* pool_infos{};
|
||||
/// The number of pools
|
||||
u64 pool_count{};
|
||||
/// Is forced mapping enabled
|
||||
bool force_map;
|
||||
};
|
||||
|
||||
} // namespace AudioCore::AudioRenderer
|
Reference in New Issue
Block a user