forked from eden-emu/eden
		
	video_core: memory_manager: Updates for Common::PageTable changes.
This commit is contained in:
		
							parent
							
								
									f7c03610e1
								
							
						
					
					
						commit
						32fc2aae3c
					
				
					 2 changed files with 34 additions and 67 deletions
				
			
		|  | @ -6,8 +6,8 @@ | ||||||
| #include "common/assert.h" | #include "common/assert.h" | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
| #include "core/core.h" | #include "core/core.h" | ||||||
|  | #include "core/hle/kernel/memory/page_table.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
| #include "core/hle/kernel/vm_manager.h" |  | ||||||
| #include "core/memory.h" | #include "core/memory.h" | ||||||
| #include "video_core/gpu.h" | #include "video_core/gpu.h" | ||||||
| #include "video_core/memory_manager.h" | #include "video_core/memory_manager.h" | ||||||
|  | @ -17,10 +17,7 @@ namespace Tegra { | ||||||
| 
 | 
 | ||||||
| MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | MemoryManager::MemoryManager(Core::System& system, VideoCore::RasterizerInterface& rasterizer) | ||||||
|     : rasterizer{rasterizer}, system{system} { |     : rasterizer{rasterizer}, system{system} { | ||||||
|     std::fill(page_table.pointers.begin(), page_table.pointers.end(), nullptr); |     page_table.Resize(address_space_width, page_bits, false); | ||||||
|     std::fill(page_table.attributes.begin(), page_table.attributes.end(), |  | ||||||
|               Common::PageType::Unmapped); |  | ||||||
|     page_table.Resize(address_space_width); |  | ||||||
| 
 | 
 | ||||||
|     // Initialize the map with a single free region covering the entire managed space.
 |     // Initialize the map with a single free region covering the entire managed space.
 | ||||||
|     VirtualMemoryArea initial_vma; |     VirtualMemoryArea initial_vma; | ||||||
|  | @ -55,9 +52,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) { | ||||||
| 
 | 
 | ||||||
|     MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); |     MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); | ||||||
|     ASSERT(system.CurrentProcess() |     ASSERT(system.CurrentProcess() | ||||||
|                ->VMManager() |                ->PageTable() | ||||||
|                .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, |                .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared, | ||||||
|                                    Kernel::MemoryAttribute::DeviceMapped) |                                    Kernel::Memory::MemoryAttribute::DeviceShared) | ||||||
|                .IsSuccess()); |                .IsSuccess()); | ||||||
| 
 | 
 | ||||||
|     return gpu_addr; |     return gpu_addr; | ||||||
|  | @ -70,9 +67,9 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size) | ||||||
| 
 | 
 | ||||||
|     MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); |     MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); | ||||||
|     ASSERT(system.CurrentProcess() |     ASSERT(system.CurrentProcess() | ||||||
|                ->VMManager() |                ->PageTable() | ||||||
|                .SetMemoryAttribute(cpu_addr, size, Kernel::MemoryAttribute::DeviceMapped, |                .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared, | ||||||
|                                    Kernel::MemoryAttribute::DeviceMapped) |                                    Kernel::Memory::MemoryAttribute::DeviceShared) | ||||||
|                .IsSuccess()); |                .IsSuccess()); | ||||||
|     return gpu_addr; |     return gpu_addr; | ||||||
| } | } | ||||||
|  | @ -89,9 +86,10 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) { | ||||||
| 
 | 
 | ||||||
|     UnmapRange(gpu_addr, aligned_size); |     UnmapRange(gpu_addr, aligned_size); | ||||||
|     ASSERT(system.CurrentProcess() |     ASSERT(system.CurrentProcess() | ||||||
|                ->VMManager() |                ->PageTable() | ||||||
|                .SetMemoryAttribute(cpu_addr.value(), size, Kernel::MemoryAttribute::DeviceMapped, |                .SetMemoryAttribute(cpu_addr.value(), size, | ||||||
|                                    Kernel::MemoryAttribute::None) |                                    Kernel::Memory::MemoryAttribute::DeviceShared, | ||||||
|  |                                    Kernel::Memory::MemoryAttribute::None) | ||||||
|                .IsSuccess()); |                .IsSuccess()); | ||||||
| 
 | 
 | ||||||
|     return gpu_addr; |     return gpu_addr; | ||||||
|  | @ -147,16 +145,8 @@ T MemoryManager::Read(GPUVAddr addr) const { | ||||||
|         return value; |         return value; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (page_table.attributes[addr >> page_bits]) { |  | ||||||
|     case Common::PageType::Unmapped: |  | ||||||
|         LOG_ERROR(HW_GPU, "Unmapped Read{} @ 0x{:08X}", sizeof(T) * 8, addr); |  | ||||||
|         return 0; |  | ||||||
|     case Common::PageType::Memory: |  | ||||||
|         ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|     UNREACHABLE(); |     UNREACHABLE(); | ||||||
|     } | 
 | ||||||
|     return {}; |     return {}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -173,18 +163,8 @@ void MemoryManager::Write(GPUVAddr addr, T data) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     switch (page_table.attributes[addr >> page_bits]) { |  | ||||||
|     case Common::PageType::Unmapped: |  | ||||||
|         LOG_ERROR(HW_GPU, "Unmapped Write{} 0x{:08X} @ 0x{:016X}", sizeof(data) * 8, |  | ||||||
|                   static_cast<u32>(data), addr); |  | ||||||
|         return; |  | ||||||
|     case Common::PageType::Memory: |  | ||||||
|         ASSERT_MSG(false, "Mapped memory page without a pointer @ {:016X}", addr); |  | ||||||
|         break; |  | ||||||
|     default: |  | ||||||
|     UNREACHABLE(); |     UNREACHABLE(); | ||||||
| } | } | ||||||
| } |  | ||||||
| 
 | 
 | ||||||
| template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; | template u8 MemoryManager::Read<u8>(GPUVAddr addr) const; | ||||||
| template u16 MemoryManager::Read<u16>(GPUVAddr addr) const; | template u16 MemoryManager::Read<u16>(GPUVAddr addr) const; | ||||||
|  | @ -249,18 +229,11 @@ void MemoryManager::ReadBlock(GPUVAddr src_addr, void* dest_buffer, const std::s | ||||||
|         const std::size_t copy_amount{ |         const std::size_t copy_amount{ | ||||||
|             std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; |             std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||||||
| 
 | 
 | ||||||
|         switch (page_table.attributes[page_index]) { |  | ||||||
|         case Common::PageType::Memory: { |  | ||||||
|         const VAddr src_addr{page_table.backing_addr[page_index] + page_offset}; |         const VAddr src_addr{page_table.backing_addr[page_index] + page_offset}; | ||||||
|         // Flush must happen on the rasterizer interface, such that memory is always synchronous
 |         // Flush must happen on the rasterizer interface, such that memory is always synchronous
 | ||||||
|         // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu.
 |         // when it is read (even when in asynchronous GPU mode). Fixes Dead Cells title menu.
 | ||||||
|         rasterizer.FlushRegion(src_addr, copy_amount); |         rasterizer.FlushRegion(src_addr, copy_amount); | ||||||
|         memory.ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); |         memory.ReadBlockUnsafe(src_addr, dest_buffer, copy_amount); | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         default: |  | ||||||
|             UNREACHABLE(); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         page_index++; |         page_index++; | ||||||
|         page_offset = 0; |         page_offset = 0; | ||||||
|  | @ -305,18 +278,11 @@ void MemoryManager::WriteBlock(GPUVAddr dest_addr, const void* src_buffer, const | ||||||
|         const std::size_t copy_amount{ |         const std::size_t copy_amount{ | ||||||
|             std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; |             std::min(static_cast<std::size_t>(page_size) - page_offset, remaining_size)}; | ||||||
| 
 | 
 | ||||||
|         switch (page_table.attributes[page_index]) { |  | ||||||
|         case Common::PageType::Memory: { |  | ||||||
|         const VAddr dest_addr{page_table.backing_addr[page_index] + page_offset}; |         const VAddr dest_addr{page_table.backing_addr[page_index] + page_offset}; | ||||||
|         // Invalidate must happen on the rasterizer interface, such that memory is always
 |         // Invalidate must happen on the rasterizer interface, such that memory is always
 | ||||||
|         // synchronous when it is written (even when in asynchronous GPU mode).
 |         // synchronous when it is written (even when in asynchronous GPU mode).
 | ||||||
|         rasterizer.InvalidateRegion(dest_addr, copy_amount); |         rasterizer.InvalidateRegion(dest_addr, copy_amount); | ||||||
|         memory.WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); |         memory.WriteBlockUnsafe(dest_addr, src_buffer, copy_amount); | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         default: |  | ||||||
|             UNREACHABLE(); |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         page_index++; |         page_index++; | ||||||
|         page_offset = 0; |         page_offset = 0; | ||||||
|  | @ -362,8 +328,8 @@ void MemoryManager::CopyBlockUnsafe(GPUVAddr dest_addr, GPUVAddr src_addr, const | ||||||
| 
 | 
 | ||||||
| bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) { | bool MemoryManager::IsGranularRange(GPUVAddr gpu_addr, std::size_t size) { | ||||||
|     const VAddr addr = page_table.backing_addr[gpu_addr >> page_bits]; |     const VAddr addr = page_table.backing_addr[gpu_addr >> page_bits]; | ||||||
|     const std::size_t page = (addr & Memory::PAGE_MASK) + size; |     const std::size_t page = (addr & Core::Memory::PAGE_MASK) + size; | ||||||
|     return page <= Memory::PAGE_SIZE; |     return page <= Core::Memory::PAGE_SIZE; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemoryManager::MapPages(GPUVAddr base, u64 size, u8* memory, Common::PageType type, | 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 | ||||||
|     ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", |     ASSERT_MSG(end <= page_table.pointers.size(), "out of range mapping at {:016X}", | ||||||
|                base + page_table.pointers.size()); |                base + page_table.pointers.size()); | ||||||
| 
 | 
 | ||||||
|     std::fill(page_table.attributes.begin() + base, page_table.attributes.begin() + end, type); |  | ||||||
| 
 |  | ||||||
|     if (memory == nullptr) { |     if (memory == nullptr) { | ||||||
|         std::fill(page_table.pointers.begin() + base, page_table.pointers.begin() + end, memory); |         while (base != end) { | ||||||
|         std::fill(page_table.backing_addr.begin() + base, page_table.backing_addr.begin() + end, |             page_table.pointers[base] = nullptr; | ||||||
|                   backing_addr); |             page_table.backing_addr[base] = 0; | ||||||
|  | 
 | ||||||
|  |             base += 1; | ||||||
|  |         } | ||||||
|     } else { |     } else { | ||||||
|         while (base != end) { |         while (base != end) { | ||||||
|             page_table.pointers[base] = memory; |             page_table.pointers[base] = memory; | ||||||
|  |  | ||||||
|  | @ -179,7 +179,7 @@ private: | ||||||
|     /// End of address space, based on address space in bits.
 |     /// End of address space, based on address space in bits.
 | ||||||
|     static constexpr GPUVAddr address_space_end{1ULL << address_space_width}; |     static constexpr GPUVAddr address_space_end{1ULL << address_space_width}; | ||||||
| 
 | 
 | ||||||
|     Common::BackingPageTable page_table{page_bits}; |     Common::PageTable page_table; | ||||||
|     VMAMap vma_map; |     VMAMap vma_map; | ||||||
|     VideoCore::RasterizerInterface& rasterizer; |     VideoCore::RasterizerInterface& rasterizer; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei