diff options
| author | 2020-04-08 22:51:31 -0400 | |
|---|---|---|
| committer | 2020-04-17 00:59:34 -0400 | |
| commit | 32fc2aae3cd767faf57e9a6f80ebae20bdfb2218 (patch) | |
| tree | 870a8fea541547dcc11866cc7159f27e4bfc31cd /src | |
| parent | core: memory: Updates for new VMM. (diff) | |
| download | yuzu-32fc2aae3cd767faf57e9a6f80ebae20bdfb2218.tar.gz yuzu-32fc2aae3cd767faf57e9a6f80ebae20bdfb2218.tar.xz yuzu-32fc2aae3cd767faf57e9a6f80ebae20bdfb2218.zip | |
video_core: memory_manager: Updates for Common::PageTable changes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/video_core/memory_manager.cpp | 99 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 2 |
2 files changed, 34 insertions, 67 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index a3389d0d2..fd49bc2a9 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/memory/page_table.h" | ||
| 9 | #include "core/hle/kernel/process.h" | 10 | #include "core/hle/kernel/process.h" |
| 10 | #include "core/hle/kernel/vm_manager.h" | ||
| 11 | #include "core/memory.h" | 11 | #include "core/memory.h" |
| 12 | #include "video_core/gpu.h" | 12 | #include "video_core/gpu.h" |
| 13 | #include "video_core/memory_manager.h" | 13 | #include "video_core/memory_manager.h" |
| @@ -17,10 +17,7 @@ namespace Tegra { | |||
| 17 | 17 | ||
| 18 | MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | 18 | MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) |
| 19 | : rasterizer{rasterizer}, system{system} { | 19 | : rasterizer{rasterizer}, system{system} { |
| 20 | std::fill(page_table.pointers.begin(), page_table.pointers.end(), nullptr); | 20 | page_table.Resize(address_space_width, page_bits, false); |
| 21 | std::fill(page_table.attributes.begin(), page_table.attributes.end(), | ||
| 22 | Common::PageType::Unmapped); | ||
| 23 | page_table.Resize(address_space_width); | ||
| 24 | 21 | ||
| 25 | // Initialize the map with a single free region covering the entire managed space. | 22 | // Initialize the map with a single free region covering the entire managed space. |
| 26 | VirtualMemoryArea initial_vma; | 23 | VirtualMemoryArea initial_vma; |
| @@ -55,9 +52,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { | |||
| 55 | 52 | ||
| 56 | MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); | 53 | MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); |
| 57 | ASSERT(system.CurrentProcess() | 54 | ASSERT(system.CurrentProcess() |
| 58 | ->VMManager() | 55 | ->PageTable() |
| 59 | .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, | 56 | .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared, |
| 60 | Kernel::MemoryAttribute::DeviceMapped) | 57 | Kernel::Memory::MemoryAttribute::DeviceShared) |
| 61 | .IsSuccess()); | 58 | .IsSuccess()); |
| 62 | 59 | ||
| 63 | return gpu_addr; | 60 | return gpu_addr; |
| @@ -70,9 +67,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) | |||
| 70 | 67 | ||
| 71 | MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); | 68 | MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); |
| 72 | ASSERT(system.CurrentProcess() | 69 | ASSERT(system.CurrentProcess() |
| 73 | ->VMManager() | 70 | ->PageTable() |
| 74 | .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, | 71 | .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared, |
| 75 | Kernel::MemoryAttribute::DeviceMapped) | 72 | Kernel::Memory::MemoryAttribute::DeviceShared) |
| 76 | .IsSuccess()); | 73 | .IsSuccess()); |
| 77 | return gpu_addr; | 74 | return gpu_addr; |
| 78 | } | 75 | } |
| @@ -89,9 +86,10 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) { | |||
| 89 | 86 | ||
| 90 | UnmapRange(gpu_addr, aligned_size); | 87 | UnmapRange(gpu_addr, aligned_size); |
| 91 | ASSERT(system.CurrentProcess() | 88 | ASSERT(system.CurrentProcess() |
| 92 | ->VMManager() | 89 | ->PageTable() |
| 93 | .SetMemoryAttribute(cpu_addr.value(), size, Kernel::MemoryAttribute::DeviceMapped, | 90 | .SetMemoryAttribute(cpu_addr.value(), size, |
| 94 | Kernel::MemoryAttribute::None) | 91 | Kernel::Memory::MemoryAttribute::DeviceShared, |
| 92 | Kernel::Memory::MemoryAttribute::None) | ||
| 95 | .IsSuccess()); | 93 | .IsSuccess()); |
| 96 | 94 | ||
| 97 | return gpu_addr; | 95 | return gpu_addr; |
| @@ -147,16 +145,8 @@ T MemoryManager::Read(GPUVAddr addr) const { | |||
| 147 | return value; | 145 | return value; |
| 148 | } | 146 | } |
| 149 | 147 | ||
| 150 | switch (page_table.attributes[addr >> page_bits]) { | 148 | UNREACHABLE(); |
| 151 | case Common::PageType::Unmapped: | 149 | |
| 152 | LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, addr); | ||
| 153 | return 0; | ||
| 154 | case Common::PageType::Memory: | ||
| 155 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); | ||
| 156 | break; | ||
| 157 | default: | ||
| 158 | UNREACHABLE(); | ||
| 159 | } | ||
| 160 | return {}; | 150 | return {}; |
| 161 | } | 151 | } |
| 162 | 152 | ||
| @@ -173,17 +163,7 @@ void MemoryManager::Write(GPUVAddr addr, T data) { | |||
| 173 | return; | 163 | return; |
| 174 | } | 164 | } |
| 175 | 165 | ||
| 176 | switch (page_table.attributes[addr >> page_bits]) { | 166 | UNREACHABLE(); |
| 177 | case Common::PageType::Unmapped: | ||
| 178 | LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | ||
| 179 | static_cast<u32>(data), addr); | ||
| 180 | return; | ||
| 181 | case Common::PageType::Memory: | ||
| 182 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); | ||
| 183 | break; | ||
| 184 | default: | ||
| 185 | UNREACHABLE(); | ||
| 186 | } | ||
| 187 | } | 167 | } |
| 188 | 168 | ||
| 189 | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; | 169 | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; |
| @@ -249,18 +229,11 @@ void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, const std::s | |||
| 249 | const std::size_t copy_amount{ | 229 | const std::size_t copy_amount{ |
| 250 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | 230 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; |
| 251 | 231 | ||
| 252 | switch (page_table.attributes[page_index]) { | 232 | const VAddr src_addr{page_table.backing_addr[page_index] + page_offset}; |
| 253 | case Common::PageType::Memory: { | 233 | // Flush must happen on the rasterizer interface, such that memory is always synchronous |
| 254 | const VAddr src_addr{page_table.backing_addr[page_index] + page_offset}; | 234 | // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. |
| 255 | // Flush must happen on the rasterizer interface, such that memory is always synchronous | 235 | rasterizer.FlushRegion(src_addr, copy_amount); |
| 256 | // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu. | 236 | memory.ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); |
| 257 | rasterizer.FlushRegion(src_addr, copy_amount); | ||
| 258 | memory.ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | ||
| 259 | break; | ||
| 260 | } | ||
| 261 | default: | ||
| 262 | UNREACHABLE(); | ||
| 263 | } | ||
| 264 | 237 | ||
| 265 | page_index++; | 238 | page_index++; |
| 266 | page_offset = 0; | 239 | page_offset = 0; |
| @@ -305,18 +278,11 @@ void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, const | |||
| 305 | const std::size_t copy_amount{ | 278 | const std::size_t copy_amount{ |
| 306 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | 279 | std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; |
| 307 | 280 | ||
| 308 | switch (page_table.attributes[page_index]) { | 281 | const VAddr dest_addr{page_table.backing_addr[page_index] + page_offset}; |
| 309 | case Common::PageType::Memory: { | 282 | // Invalidate must happen on the rasterizer interface, such that memory is always |
| 310 | const VAddr dest_addr{page_table.backing_addr[page_index] + page_offset}; | 283 | // synchronous when it is written (even when in asynchronous GPU mode). |
| 311 | // Invalidate must happen on the rasterizer interface, such that memory is always | 284 | rasterizer.InvalidateRegion(dest_addr, copy_amount); |
| 312 | // synchronous when it is written (even when in asynchronous GPU mode). | 285 | memory.WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); |
| 313 | rasterizer.InvalidateRegion(dest_addr, copy_amount); | ||
| 314 | memory.WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | ||
| 315 | break; | ||
| 316 | } | ||
| 317 | default: | ||
| 318 | UNREACHABLE(); | ||
| 319 | } | ||
| 320 | 286 | ||
| 321 | page_index++; | 287 | page_index++; |
| 322 | page_offset = 0; | 288 | page_offset = 0; |
| @@ -362,8 +328,8 @@ void MemoryManager::CopyBlockUnsafe(GPUVAddr dest_addr, GPUVAddr src_addr, const | |||
| 362 | 328 | ||
| 363 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) { | 329 | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) { |
| 364 | const VAddr addr = page_table.backing_addr[gpu_addr >> page_bits]; | 330 | const VAddr addr = page_table.backing_addr[gpu_addr >> page_bits]; |
| 365 | const std::size_t page = (addr & Memory::PAGE_MASK) + size; | 331 | const std::size_t page = (addr & Core::Memory::PAGE_MASK) + size; |
| 366 | return page <= Memory::PAGE_SIZE; | 332 | return page <= Core::Memory::PAGE_SIZE; |
| 367 | } | 333 | } |
| 368 | 334 | ||
| 369 | void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, | 335 | void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, |
| @@ -375,12 +341,13 @@ void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageTy | |||
| 375 | ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", | 341 | ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", |
| 376 | base + page_table.pointers.size()); | 342 | base + page_table.pointers.size()); |
| 377 | 343 | ||
| 378 | std::fill(page_table.attributes.begin() + base, page_table.attributes.begin() + end, type); | ||
| 379 | |||
| 380 | if (memory == nullptr) { | 344 | if (memory == nullptr) { |
| 381 | std::fill(page_table.pointers.begin() + base, page_table.pointers.begin() + end, memory); | 345 | while (base != end) { |
| 382 | std::fill(page_table.backing_addr.begin() + base, page_table.backing_addr.begin() + end, | 346 | page_table.pointers[base] = nullptr; |
| 383 | backing_addr); | 347 | page_table.backing_addr[base] = 0; |
| 348 | |||
| 349 | base += 1; | ||
| 350 | } | ||
| 384 | } else { | 351 | } else { |
| 385 | while (base != end) { | 352 | while (base != end) { |
| 386 | page_table.pointers[base] = memory; | 353 | page_table.pointers[base] = memory; |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index 0d9468535..0ddd52d5a 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -179,7 +179,7 @@ private: | |||
| 179 | /// End of address space, based on address space in bits. | 179 | /// End of address space, based on address space in bits. |
| 180 | static constexpr GPUVAddr address_space_end{1ULL << address_space_width}; | 180 | static constexpr GPUVAddr address_space_end{1ULL << address_space_width}; |
| 181 | 181 | ||
| 182 | Common::BackingPageTable page_table{page_bits}; | 182 | Common::PageTable page_table; |
| 183 | VMAMap vma_map; | 183 | VMAMap vma_map; |
| 184 | VideoCore::RasterizerInterface& rasterizer; | 184 | VideoCore::RasterizerInterface& rasterizer; |
| 185 | 185 | ||