diff options
Diffstat (limited to 'src/video_core')
| -rw-r--r-- | src/video_core/memory_manager.cpp | 50 | ||||
| -rw-r--r-- | src/video_core/memory_manager.h | 15 |
2 files changed, 43 insertions, 22 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 4c7faa067..e8edf9b14 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp | |||
| @@ -90,32 +90,44 @@ GPUVAddr MemoryManager::FindFreeRegion(GPUVAddr region_start, u64 size, u64 alig | |||
| 90 | return std::max(base, vma_handle->second.base); | 90 | return std::max(base, vma_handle->second.base); |
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr gpu_addr) { | 93 | bool MemoryManager::IsAddressValid(GPUVAddr addr) const { |
| 94 | VAddr cpu_addr = page_table.backing_addr[gpu_addr >> page_bits]; | 94 | return (addr >> page_bits) < page_table.pointers.size(); |
| 95 | } | ||
| 96 | |||
| 97 | std::optional<VAddr> MemoryManager::GpuToCpuAddress(GPUVAddr addr) { | ||
| 98 | if (!IsAddressValid(addr)) { | ||
| 99 | return {}; | ||
| 100 | } | ||
| 101 | |||
| 102 | VAddr cpu_addr = page_table.backing_addr[addr >> page_bits]; | ||
| 95 | if (cpu_addr) { | 103 | if (cpu_addr) { |
| 96 | return cpu_addr + (gpu_addr & page_mask); | 104 | return cpu_addr + (addr & page_mask); |
| 97 | } | 105 | } |
| 98 | 106 | ||
| 99 | return {}; | 107 | return {}; |
| 100 | } | 108 | } |
| 101 | 109 | ||
| 102 | template <typename T> | 110 | template <typename T> |
| 103 | T MemoryManager::Read(GPUVAddr vaddr) { | 111 | T MemoryManager::Read(GPUVAddr addr) { |
| 104 | const u8* page_pointer = page_table.pointers[vaddr >> page_bits]; | 112 | if (!IsAddressValid(addr)) { |
| 113 | return {}; | ||
| 114 | } | ||
| 115 | |||
| 116 | const u8* page_pointer = page_table.pointers[addr >> page_bits]; | ||
| 105 | if (page_pointer) { | 117 | if (page_pointer) { |
| 106 | // NOTE: Avoid adding any extra logic to this fast-path block | 118 | // NOTE: Avoid adding any extra logic to this fast-path block |
| 107 | T value; | 119 | T value; |
| 108 | std::memcpy(&value, &page_pointer[vaddr & page_mask], sizeof(T)); | 120 | std::memcpy(&value, &page_pointer[addr & page_mask], sizeof(T)); |
| 109 | return value; | 121 | return value; |
| 110 | } | 122 | } |
| 111 | 123 | ||
| 112 | Common::PageType type = page_table.attributes[vaddr >> page_bits]; | 124 | Common::PageType type = page_table.attributes[addr >> page_bits]; |
| 113 | switch (type) { | 125 | switch (type) { |
| 114 | case Common::PageType::Unmapped: | 126 | case Common::PageType::Unmapped: |
| 115 | LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, vaddr); | 127 | LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, addr); |
| 116 | return 0; | 128 | return 0; |
| 117 | case Common::PageType::Memory: | 129 | case Common::PageType::Memory: |
| 118 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); | 130 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); |
| 119 | break; | 131 | break; |
| 120 | default: | 132 | default: |
| 121 | UNREACHABLE(); | 133 | UNREACHABLE(); |
| @@ -124,22 +136,26 @@ T MemoryManager::Read(GPUVAddr vaddr) { | |||
| 124 | } | 136 | } |
| 125 | 137 | ||
| 126 | template <typename T> | 138 | template <typename T> |
| 127 | void MemoryManager::Write(GPUVAddr vaddr, T data) { | 139 | void MemoryManager::Write(GPUVAddr addr, T data) { |
| 128 | u8* page_pointer = page_table.pointers[vaddr >> page_bits]; | 140 | if (!IsAddressValid(addr)) { |
| 141 | return; | ||
| 142 | } | ||
| 143 | |||
| 144 | u8* page_pointer = page_table.pointers[addr >> page_bits]; | ||
| 129 | if (page_pointer) { | 145 | if (page_pointer) { |
| 130 | // NOTE: Avoid adding any extra logic to this fast-path block | 146 | // NOTE: Avoid adding any extra logic to this fast-path block |
| 131 | std::memcpy(&page_pointer[vaddr & page_mask], &data, sizeof(T)); | 147 | std::memcpy(&page_pointer[addr & page_mask], &data, sizeof(T)); |
| 132 | return; | 148 | return; |
| 133 | } | 149 | } |
| 134 | 150 | ||
| 135 | Common::PageType type = page_table.attributes[vaddr >> page_bits]; | 151 | Common::PageType type = page_table.attributes[addr >> page_bits]; |
| 136 | switch (type) { | 152 | switch (type) { |
| 137 | case Common::PageType::Unmapped: | 153 | case Common::PageType::Unmapped: |
| 138 | LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, | 154 | LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, |
| 139 | static_cast<u32>(data), vaddr); | 155 | static_cast<u32>(data), addr); |
| 140 | return; | 156 | return; |
| 141 | case Common::PageType::Memory: | 157 | case Common::PageType::Memory: |
| 142 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", vaddr); | 158 | ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); |
| 143 | break; | 159 | break; |
| 144 | default: | 160 | default: |
| 145 | UNREACHABLE(); | 161 | UNREACHABLE(); |
| @@ -156,6 +172,10 @@ template void MemoryManager::Write<u32>(GPUVAddr addr, u32 data); | |||
| 156 | template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data); | 172 | template void MemoryManager::Write<u64>(GPUVAddr addr, u64 data); |
| 157 | 173 | ||
| 158 | u8* MemoryManager::GetPointer(GPUVAddr addr) { | 174 | u8* MemoryManager::GetPointer(GPUVAddr addr) { |
| 175 | if (!IsAddressValid(addr)) { | ||
| 176 | return {}; | ||
| 177 | } | ||
| 178 | |||
| 159 | u8* page_pointer = page_table.pointers[addr >> page_bits]; | 179 | u8* page_pointer = page_table.pointers[addr >> page_bits]; |
| 160 | if (page_pointer) { | 180 | if (page_pointer) { |
| 161 | return page_pointer + (addr & page_mask); | 181 | return page_pointer + (addr & page_mask); |
diff --git a/src/video_core/memory_manager.h b/src/video_core/memory_manager.h index ac1b42936..76fa3d916 100644 --- a/src/video_core/memory_manager.h +++ b/src/video_core/memory_manager.h | |||
| @@ -46,19 +46,19 @@ public: | |||
| 46 | MemoryManager(); | 46 | MemoryManager(); |
| 47 | 47 | ||
| 48 | GPUVAddr AllocateSpace(u64 size, u64 align); | 48 | GPUVAddr AllocateSpace(u64 size, u64 align); |
| 49 | GPUVAddr AllocateSpace(GPUVAddr gpu_addr, u64 size, u64 align); | 49 | GPUVAddr AllocateSpace(GPUVAddr addr, u64 size, u64 align); |
| 50 | GPUVAddr MapBufferEx(GPUVAddr cpu_addr, u64 size); | 50 | GPUVAddr MapBufferEx(GPUVAddr cpu_addr, u64 size); |
| 51 | GPUVAddr MapBufferEx(GPUVAddr cpu_addr, GPUVAddr gpu_addr, u64 size); | 51 | GPUVAddr MapBufferEx(GPUVAddr cpu_addr, GPUVAddr addr, u64 size); |
| 52 | GPUVAddr UnmapBuffer(GPUVAddr gpu_addr, u64 size); | 52 | GPUVAddr UnmapBuffer(GPUVAddr addr, u64 size); |
| 53 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr gpu_addr); | 53 | std::optional<VAddr> GpuToCpuAddress(GPUVAddr addr); |
| 54 | 54 | ||
| 55 | template <typename T> | 55 | template <typename T> |
| 56 | T Read(GPUVAddr vaddr); | 56 | T Read(GPUVAddr addr); |
| 57 | 57 | ||
| 58 | template <typename T> | 58 | template <typename T> |
| 59 | void Write(GPUVAddr vaddr, T data); | 59 | void Write(GPUVAddr addr, T data); |
| 60 | 60 | ||
| 61 | u8* GetPointer(GPUVAddr vaddr); | 61 | u8* GetPointer(GPUVAddr addr); |
| 62 | 62 | ||
| 63 | void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size); | 63 | void ReadBlock(GPUVAddr src_addr, void* dest_buffer, std::size_t size); |
| 64 | void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size); | 64 | void WriteBlock(GPUVAddr dest_addr, const void* src_buffer, std::size_t size); |
| @@ -69,6 +69,7 @@ private: | |||
| 69 | using VMAHandle = VMAMap::const_iterator; | 69 | using VMAHandle = VMAMap::const_iterator; |
| 70 | using VMAIter = VMAMap::iterator; | 70 | using VMAIter = VMAMap::iterator; |
| 71 | 71 | ||
| 72 | bool IsAddressValid(GPUVAddr addr) const; | ||
| 72 | void MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, | 73 | void MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, |
| 73 | VAddr backing_addr = 0); | 74 | VAddr backing_addr = 0); |
| 74 | void MapMemoryRegion(GPUVAddr base, u64 size, u8* target, VAddr backing_addr); | 75 | void MapMemoryRegion(GPUVAddr base, u64 size, u8* target, VAddr backing_addr); |