diff options
| -rw-r--r-- | src/video_core/memory_manager.cpp | 51 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 9 |
2 files changed, 38 insertions, 22 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index e76b59842..8417324ff 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -77,16 +77,17 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) { | |||
| 77 | return gpu_addr; | 77 | return gpu_addr; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | GPUVAddr MemoryManager::FindFreeRegion(GPUVAddr region_start, u64 size) { | 80 | GPUVAddr MemoryManager::FindFreeRegion(GPUVAddr region_start, u64 size) const { |
| 81 | // Find the first Free VMA. | 81 | // Find the first Free VMA. |
| 82 | const VMAHandle vma_handle{std::find_if(vma_map.begin(), vma_map.end(), [&](const auto& vma) { | 82 | const VMAHandle vma_handle{ |
| 83 | if (vma.second.type != VirtualMemoryArea::Type::Unmapped) { | 83 | std::find_if(vma_map.begin(), vma_map.end(), [region_start, size](const auto& vma) { |
| 84 | return false; | 84 | if (vma.second.type != VirtualMemoryArea::Type::Unmapped) { |
| 85 | } | 85 | return false; |
| 86 | } | ||
| 86 | 87 | ||
| 87 | const VAddr vma_end{vma.second.base + vma.second.size}; | 88 | const VAddr vma_end{vma.second.base + vma.second.size}; |
| 88 | return vma_end > region_start && vma_end >= region_start + size; | 89 | return vma_end > region_start && vma_end >= region_start + size; |
| 89 | })}; | 90 | })}; |
| 90 | 91 | ||
| 91 | if (vma_handle == vma_map.end()) { | 92 | if (vma_handle == vma_map.end()) { |
| 92 | return {}; | 93 | return {}; |
| @@ -99,12 +100,12 @@ bool MemoryManager::IsAddressValid(GPUVAddr addr) const { | |||
| 99 | return (addr >> page_bits) < page_table.pointers.size(); | 100 | return (addr >> page_bits) < page_table.pointers.size(); |
| 100 | } | 101 | } |
| 101 | 102 | ||
| 102 | std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) { | 103 | std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) const { |
| 103 | if (!IsAddressValid(addr)) { | 104 | if (!IsAddressValid(addr)) { |
| 104 | return {}; | 105 | return {}; |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | VAddr cpu_addr{page_table.backing_addr[addr >> page_bits]}; | 108 | const VAddr cpu_addr{page_table.backing_addr[addr >> page_bits]}; |
| 108 | if (cpu_addr) { | 109 | if (cpu_addr) { |
| 109 | return cpu_addr + (addr & page_mask); | 110 | return cpu_addr + (addr & page_mask); |
| 110 | } | 111 | } |
| @@ -113,7 +114,7 @@ std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) { | |||
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | template <typename T> | 116 | template <typename T> |
| 116 | T MemoryManager::Read(GPUVAddr addr) { | 117 | T MemoryManager::Read(GPUVAddr addr) const { |
| 117 | if (!IsAddressValid(addr)) { | 118 | if (!IsAddressValid(addr)) { |
| 118 | return {}; | 119 | return {}; |
| 119 | } | 120 | } |
| @@ -165,10 +166,10 @@ void MemoryManager::Write(GPUVAddr addr, T data) { | |||
| 165 | } | 166 | } |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | template u8 MemoryManager::Read<u8>(GPUVAddr addr); | 169 | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; |
| 169 | template u16 MemoryManager::Read<u16>(GPUVAddr addr); | 170 | template u16 MemoryManager::Read<u16>(GPUVAddr addr) const; |
| 170 | template u32 MemoryManager::Read<u32>(GPUVAddr addr); | 171 | template u32 MemoryManager::Read<u32>(GPUVAddr addr) const; |
| 171 | template u64 MemoryManager::Read<u64>(GPUVAddr addr); | 172 | template u64 MemoryManager::Read<u64>(GPUVAddr addr) const; |
| 172 | template void MemoryManager::Write<u8>(GPUVAddr addr, u8 data); | 173 | template void MemoryManager::Write<u8>(GPUVAddr addr, u8 data); |
| 173 | template void MemoryManager::Write<u16>(GPUVAddr addr, u16 data); | 174 | template void MemoryManager::Write<u16>(GPUVAddr addr, u16 data); |
| 174 | template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data); | 175 | template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data); |
| @@ -179,8 +180,22 @@ u8* MemoryManager::GetPointer(GPUVAddr addr) { | |||
| 179 | return {}; | 180 | return {}; |
| 180 | } | 181 | } |
| 181 | 182 | ||
| 182 | u8* page_pointer{page_table.pointers[addr >> page_bits]}; | 183 | u8* const page_pointer{page_table.pointers[addr >> page_bits]}; |
| 183 | if (page_pointer) { | 184 | if (page_pointer != nullptr) { |
| 185 | return page_pointer + (addr & page_mask); | ||
| 186 | } | ||
| 187 | |||
| 188 | LOG_ERROR(HW_GPU, "Unknown GetPointer @ 0x{:016X}", addr); | ||
| 189 | return {}; | ||
| 190 | } | ||
| 191 | |||
| 192 | const u8* MemoryManager::GetPointer(GPUVAddr addr) const { | ||
| 193 | if (!IsAddressValid(addr)) { | ||
| 194 | return {}; | ||
| 195 | } | ||
| 196 | |||
| 197 | const u8* const page_pointer{page_table.pointers[addr >> page_bits]}; | ||
| 198 | if (page_pointer != nullptr) { | ||
| 184 | return page_pointer + (addr & page_mask); | 199 | return page_pointer + (addr & page_mask); |
| 185 | } | 200 | } |
| 186 | 201 | ||
| @@ -188,7 +203,7 @@ u8* MemoryManager::GetPointer(GPUVAddr addr) { | |||
| 188 | return {}; | 203 | return {}; |
| 189 | } | 204 | } |
| 190 | 205 | ||
| 191 | void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) { | 206 | void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const { |
| 192 | std::memcpy(dest_buffer, GetPointer(src_addr), size); | 207 | std::memcpy(dest_buffer, GetPointer(src_addr), size); |
| 193 | } | 208 | } |
| 194 | void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { | 209 | void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size) { |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 34744bb27..178e2f655 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -50,17 +50,18 @@ public: | |||
| 50 | GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); | 50 | GPUVAddr MapBufferEx(VAddr cpu_addr, u64 size); |
| 51 | GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr addr, u64 size); | 51 | GPUVAddr MapBufferEx(VAddr cpu_addr, GPUVAddr addr, u64 size); |
| 52 | GPUVAddr UnmapBuffer(GPUVAddr addr, u64 size); | 52 | GPUVAddr UnmapBuffer(GPUVAddr addr, u64 size); |
| 53 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr); | 53 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr) const; |
| 54 | 54 | ||
| 55 | template <typename T> | 55 | template <typename T> |
| 56 | T Read(GPUVAddr addr); | 56 | T Read(GPUVAddr addr) const; |
| 57 | 57 | ||
| 58 | template <typename T> | 58 | template <typename T> |
| 59 | void Write(GPUVAddr addr, T data); | 59 | void Write(GPUVAddr addr, T data); |
| 60 | 60 | ||
| 61 | u8* GetPointer(GPUVAddr addr); | 61 | u8* GetPointer(GPUVAddr addr); |
| 62 | const u8* GetPointer(GPUVAddr addr) const; | ||
| 62 | 63 | ||
| 63 | void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size); | 64 | void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size) const; |
| 64 | void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size); | 65 | void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size); |
| 65 | void CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size); | 66 | void CopyBlock(GPUVAddr dest_addr, GPUVAddr src_addr, std::size_t size); |
| 66 | 67 | ||
| @@ -127,7 +128,7 @@ private: | |||
| 127 | void UpdatePageTableForVMA(const VirtualMemoryArea& vma); | 128 | void UpdatePageTableForVMA(const VirtualMemoryArea& vma); |
| 128 | 129 | ||
| 129 | /// Finds a free (unmapped region) of the specified size starting at the specified address. | 130 | /// Finds a free (unmapped region) of the specified size starting at the specified address. |
| 130 | GPUVAddr FindFreeRegion(GPUVAddr region_start, u64 size); | 131 | GPUVAddr FindFreeRegion(GPUVAddr region_start, u64 size) const; |
| 131 | 132 | ||
| 132 | private: | 133 | private: |
| 133 | static constexpr u64 page_bits{16}; | 134 | static constexpr u64 page_bits{16}; |