mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-05-20 18:34:58 +00:00
core: Rework memory manager
This commit is contained in:
parent
623b1d6837
commit
fc887bf3f5
10 changed files with 339 additions and 179 deletions
|
@ -4,6 +4,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <boost/icl/split_interval_map.hpp>
|
||||
|
@ -11,6 +12,7 @@
|
|||
#include "common/singleton.h"
|
||||
#include "common/types.h"
|
||||
#include "core/address_space.h"
|
||||
#include "core/libraries/kernel/memory_management.h"
|
||||
#include "video_core/renderer_vulkan/vk_common.h"
|
||||
|
||||
namespace Vulkan {
|
||||
|
@ -47,12 +49,28 @@ enum class VMAType : u32 {
|
|||
Flexible = 3,
|
||||
Pooled = 4,
|
||||
Stack = 5,
|
||||
Code = 6,
|
||||
};
|
||||
|
||||
struct DirectMemoryArea {
|
||||
PAddr base = 0;
|
||||
size_t size = 0;
|
||||
int memory_type = 0;
|
||||
bool is_free = true;
|
||||
|
||||
PAddr GetEnd() const {
|
||||
return base + size;
|
||||
}
|
||||
|
||||
bool CanMergeWith(const DirectMemoryArea& next) const {
|
||||
if (base + size != next.base) {
|
||||
return false;
|
||||
}
|
||||
if (is_free != next.is_free) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct VirtualMemoryArea {
|
||||
|
@ -81,14 +99,10 @@ struct VirtualMemoryArea {
|
|||
}
|
||||
};
|
||||
|
||||
constexpr VAddr SYSTEM_RESERVED = 0x800000000ULL;
|
||||
constexpr VAddr CODE_BASE_OFFSET = 0x100000000ULL;
|
||||
constexpr VAddr SYSTEM_MANAGED_MIN = 0x0000040000ULL;
|
||||
constexpr VAddr SYSTEM_MANAGED_MAX = 0x07FFFFBFFFULL;
|
||||
constexpr VAddr USER_MIN = 0x1000000000ULL;
|
||||
constexpr VAddr USER_MAX = 0xFBFFFFFFFFULL;
|
||||
|
||||
class MemoryManager {
|
||||
using DMemMap = std::map<PAddr, DirectMemoryArea>;
|
||||
using DMemHandle = DMemMap::iterator;
|
||||
|
||||
using VMAMap = std::map<VAddr, VirtualMemoryArea>;
|
||||
using VMAHandle = VMAMap::iterator;
|
||||
|
||||
|
@ -107,35 +121,57 @@ public:
|
|||
|
||||
int MapMemory(void** out_addr, VAddr virtual_addr, size_t size, MemoryProt prot,
|
||||
MemoryMapFlags flags, VMAType type, std::string_view name = "",
|
||||
PAddr phys_addr = -1, u64 alignment = 0);
|
||||
bool is_exec = false, PAddr phys_addr = -1, u64 alignment = 0);
|
||||
|
||||
void UnmapMemory(VAddr virtual_addr, size_t size);
|
||||
|
||||
int QueryProtection(VAddr addr, void** start, void** end, u32* prot);
|
||||
|
||||
int VirtualQuery(VAddr addr, int flags, Libraries::Kernel::OrbisVirtualQueryInfo* info);
|
||||
|
||||
int DirectMemoryQuery(PAddr addr, bool find_next, Libraries::Kernel::OrbisQueryInfo* out_info);
|
||||
|
||||
VAddr Reserve(size_t size, u64 alignment) {
|
||||
return reinterpret_cast<VAddr>(impl.Reserve(size, alignment));
|
||||
}
|
||||
int DirectQueryAvailable(PAddr search_start, PAddr search_end, size_t alignment,
|
||||
PAddr* phys_addr_out, size_t* size_out);
|
||||
|
||||
std::pair<vk::Buffer, size_t> GetVulkanBuffer(VAddr addr);
|
||||
|
||||
private:
|
||||
VMAHandle FindVMA(VAddr target) {
|
||||
// Return first the VMA with base >= target.
|
||||
const auto it = vma_map.lower_bound(target);
|
||||
if (it != vma_map.end() && it->first == target) {
|
||||
return it;
|
||||
return std::prev(vma_map.upper_bound(target));
|
||||
}
|
||||
|
||||
DMemHandle FindDmemArea(PAddr target) {
|
||||
return std::prev(dmem_map.upper_bound(target));
|
||||
}
|
||||
|
||||
template <typename Handle>
|
||||
Handle MergeAdjacent(auto& handle_map, Handle iter) {
|
||||
const auto next_vma = std::next(iter);
|
||||
if (next_vma != handle_map.end() && iter->second.CanMergeWith(next_vma->second)) {
|
||||
iter->second.size += next_vma->second.size;
|
||||
handle_map.erase(next_vma);
|
||||
}
|
||||
return std::prev(it);
|
||||
|
||||
if (iter != handle_map.begin()) {
|
||||
auto prev_vma = std::prev(iter);
|
||||
if (prev_vma->second.CanMergeWith(iter->second)) {
|
||||
prev_vma->second.size += iter->second.size;
|
||||
handle_map.erase(iter);
|
||||
iter = prev_vma;
|
||||
}
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
VirtualMemoryArea& AddMapping(VAddr virtual_addr, size_t size);
|
||||
|
||||
DirectMemoryArea& AddDmemAllocation(PAddr addr, size_t size);
|
||||
|
||||
VMAHandle Split(VMAHandle vma_handle, size_t offset_in_vma);
|
||||
|
||||
VMAHandle MergeAdjacent(VMAHandle iter);
|
||||
DMemHandle Split(DMemHandle dmem_handle, size_t offset_in_area);
|
||||
|
||||
void MapVulkanMemory(VAddr addr, size_t size);
|
||||
|
||||
|
@ -143,8 +179,9 @@ private:
|
|||
|
||||
private:
|
||||
AddressSpace impl;
|
||||
std::vector<DirectMemoryArea> allocations;
|
||||
DMemMap dmem_map;
|
||||
VMAMap vma_map;
|
||||
std::recursive_mutex mutex;
|
||||
|
||||
struct MappedMemory {
|
||||
vk::UniqueBuffer buffer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue