diff options
| author | 2019-07-08 22:19:27 -0700 | |
|---|---|---|
| committer | 2019-07-08 22:52:05 -0700 | |
| commit | 697206092e8ac28c7dfe83eff0eea6613082740c (patch) | |
| tree | 587b19d4fbf727a88524fefff496c2c12d9f7f97 | |
| parent | Remove unused member function declaration (diff) | |
| download | yuzu-697206092e8ac28c7dfe83eff0eea6613082740c.tar.gz yuzu-697206092e8ac28c7dfe83eff0eea6613082740c.tar.xz yuzu-697206092e8ac28c7dfe83eff0eea6613082740c.zip | |
Prevent merging of device mapped memory blocks.
This sets the DeviceMapped attribute for GPU-mapped memory blocks,
and prevents merging device mapped blocks. This prevents memory
mapped from the gpu from having its backing address changed by
block coalesce.
| -rw-r--r-- | src/core/hle/kernel/vm_manager.cpp | 5 | ||||
| -rw-r--r-- | src/video_core/memory_manager.cpp | 24 |
2 files changed, 28 insertions, 1 deletions
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp index 775d170bf..72a9d7717 100644 --- a/src/core/hle/kernel/vm_manager.cpp +++ b/src/core/hle/kernel/vm_manager.cpp | |||
| @@ -51,6 +51,11 @@ bool VirtualMemoryArea::CanBeMergedWith(const VirtualMemoryArea& next) const { | |||
| 51 | type != next.type) { | 51 | type != next.type) { |
| 52 | return false; | 52 | return false; |
| 53 | } | 53 | } |
| 54 | if ((attribute & MemoryAttribute::DeviceMapped) == MemoryAttribute::DeviceMapped) { | ||
| 55 | // TODO: Can device mapped memory be merged sanely? | ||
| 56 | // Not merging it may cause inaccuracies versus hardware when memory layout is queried. | ||
| 57 | return false; | ||
| 58 | } | ||
| 54 | if (type == VMAType::AllocatedMemoryBlock) { | 59 | if (type == VMAType::AllocatedMemoryBlock) { |
| 55 | return true; | 60 | return true; |
| 56 | } | 61 | } |
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 322453116..3a158fa26 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -5,6 +5,9 @@ | |||
| 5 | #include "common/alignment.h" | 5 | #include "common/alignment.h" |
| 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" | ||
| 9 | #include "core/hle/kernel/process.h" | ||
| 10 | #include "core/hle/kernel/vm_manager.h" | ||
| 8 | #include "core/memory.h" | 11 | #include "core/memory.h" |
| 9 | #include "video_core/memory_manager.h" | 12 | #include "video_core/memory_manager.h" |
| 10 | #include "video_core/rasterizer_interface.h" | 13 | #include "video_core/rasterizer_interface.h" |
| @@ -49,6 +52,12 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { | |||
| 49 | const GPUVAddr gpu_addr{FindFreeRegion(address_space_base, aligned_size)}; | 52 | const GPUVAddr gpu_addr{FindFreeRegion(address_space_base, aligned_size)}; |
| 50 | 53 | ||
| 51 | MapBackingMemory(gpu_addr, Memory::GetPointer(cpu_addr), aligned_size, cpu_addr); | 54 | MapBackingMemory(gpu_addr, Memory::GetPointer(cpu_addr), aligned_size, cpu_addr); |
| 55 | ASSERT(Core::System::GetInstance() | ||
| 56 | .CurrentProcess() | ||
| 57 | ->VMManager() | ||
| 58 | .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, | ||
| 59 | Kernel::MemoryAttribute::DeviceMapped) | ||
| 60 | .IsSuccess()); | ||
| 52 | 61 | ||
| 53 | return gpu_addr; | 62 | return gpu_addr; |
| 54 | } | 63 | } |
| @@ -59,7 +68,12 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) | |||
| 59 | const u64 aligned_size{Common::AlignUp(size, page_size)}; | 68 | const u64 aligned_size{Common::AlignUp(size, page_size)}; |
| 60 | 69 | ||
| 61 | MapBackingMemory(gpu_addr, Memory::GetPointer(cpu_addr), aligned_size, cpu_addr); | 70 | MapBackingMemory(gpu_addr, Memory::GetPointer(cpu_addr), aligned_size, cpu_addr); |
| 62 | 71 | ASSERT(Core::System::GetInstance() | |
| 72 | .CurrentProcess() | ||
| 73 | ->VMManager() | ||
| 74 | .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, | ||
| 75 | Kernel::MemoryAttribute::DeviceMapped) | ||
| 76 | .IsSuccess()); | ||
| 63 | return gpu_addr; | 77 | return gpu_addr; |
| 64 | } | 78 | } |
| 65 | 79 | ||
| @@ -68,9 +82,17 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) { | |||
| 68 | 82 | ||
| 69 | const u64 aligned_size{Common::AlignUp(size, page_size)}; | 83 | const u64 aligned_size{Common::AlignUp(size, page_size)}; |
| 70 | const CacheAddr cache_addr{ToCacheAddr(GetPointer(gpu_addr))}; | 84 | const CacheAddr cache_addr{ToCacheAddr(GetPointer(gpu_addr))}; |
| 85 | const auto cpu_addr = GpuToCpuAddress(gpu_addr); | ||
| 86 | ASSERT(cpu_addr); | ||
| 71 | 87 | ||
| 72 | rasterizer.FlushAndInvalidateRegion(cache_addr, aligned_size); | 88 | rasterizer.FlushAndInvalidateRegion(cache_addr, aligned_size); |
| 73 | UnmapRange(gpu_addr, aligned_size); | 89 | UnmapRange(gpu_addr, aligned_size); |
| 90 | ASSERT(Core::System::GetInstance() | ||
| 91 | .CurrentProcess() | ||
| 92 | ->VMManager() | ||
| 93 | .SetMemoryAttribute(cpu_addr.value(), size, Kernel::MemoryAttribute::DeviceMapped, | ||
| 94 | Kernel::MemoryAttribute::None) | ||
| 95 | .IsSuccess()); | ||
| 74 | 96 | ||
| 75 | return gpu_addr; | 97 | return gpu_addr; |
| 76 | } | 98 | } |