forked from eden-emu/eden
		
	Merge pull request #5795 from ReinUsesLisp/bytes-to-map-end
video_core/memory_manager: Add BytesToMapEnd
This commit is contained in:
		
						commit
						15108fcea7
					
				
					 2 changed files with 27 additions and 2 deletions
				
			
		|  | @ -4,6 +4,7 @@ | ||||||
| 
 | 
 | ||||||
| #include "common/alignment.h" | #include "common/alignment.h" | ||||||
| #include "common/assert.h" | #include "common/assert.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/memory/page_table.h" | ||||||
| #include "core/hle/kernel/process.h" | #include "core/hle/kernel/process.h" | ||||||
|  | @ -38,6 +39,12 @@ GPUVAddr MemoryManager::UpdateRange(GPUVAddr gpu_addr, PageEntry page_entry, std | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GPUVAddr MemoryManager::Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size) { | GPUVAddr MemoryManager::Map(VAddr cpu_addr, GPUVAddr gpu_addr, std::size_t size) { | ||||||
|  |     const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first); | ||||||
|  |     if (it != map_ranges.end() && it->first == gpu_addr) { | ||||||
|  |         it->second = size; | ||||||
|  |     } else { | ||||||
|  |         map_ranges.insert(it, MapRange{gpu_addr, size}); | ||||||
|  |     } | ||||||
|     return UpdateRange(gpu_addr, cpu_addr, size); |     return UpdateRange(gpu_addr, cpu_addr, size); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -52,10 +59,16 @@ GPUVAddr MemoryManager::MapAllocate32(VAddr cpu_addr, std::size_t size) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) { | void MemoryManager::Unmap(GPUVAddr gpu_addr, std::size_t size) { | ||||||
|     if (!size) { |     if (size == 0) { | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 |     const auto it = std::ranges::lower_bound(map_ranges, gpu_addr, {}, &MapRange::first); | ||||||
|  |     if (it != map_ranges.end()) { | ||||||
|  |         ASSERT(it->first == gpu_addr); | ||||||
|  |         map_ranges.erase(it); | ||||||
|  |     } else { | ||||||
|  |         UNREACHABLE_MSG("Unmapping non-existent GPU address=0x{:x}", gpu_addr); | ||||||
|  |     } | ||||||
|     // Flush and invalidate through the GPU interface, to be asynchronous if possible.
 |     // Flush and invalidate through the GPU interface, to be asynchronous if possible.
 | ||||||
|     const std::optional<VAddr> cpu_addr = GpuToCpuAddress(gpu_addr); |     const std::optional<VAddr> cpu_addr = GpuToCpuAddress(gpu_addr); | ||||||
|     ASSERT(cpu_addr); |     ASSERT(cpu_addr); | ||||||
|  | @ -218,6 +231,12 @@ const u8* MemoryManager::GetPointer(GPUVAddr gpu_addr) const { | ||||||
|     return system.Memory().GetPointer(*address); |     return system.Memory().GetPointer(*address); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | size_t MemoryManager::BytesToMapEnd(GPUVAddr gpu_addr) const noexcept { | ||||||
|  |     auto it = std::ranges::upper_bound(map_ranges, gpu_addr, {}, &MapRange::first); | ||||||
|  |     --it; | ||||||
|  |     return it->second - (gpu_addr - it->first); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { | void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::size_t size) const { | ||||||
|     std::size_t remaining_size{size}; |     std::size_t remaining_size{size}; | ||||||
|     std::size_t page_index{gpu_src_addr >> page_bits}; |     std::size_t page_index{gpu_src_addr >> page_bits}; | ||||||
|  |  | ||||||
|  | @ -85,6 +85,9 @@ public: | ||||||
|     [[nodiscard]] u8* GetPointer(GPUVAddr addr); |     [[nodiscard]] u8* GetPointer(GPUVAddr addr); | ||||||
|     [[nodiscard]] const u8* GetPointer(GPUVAddr addr) const; |     [[nodiscard]] const u8* GetPointer(GPUVAddr addr) const; | ||||||
| 
 | 
 | ||||||
|  |     /// Returns the number of bytes until the end of the memory map containing the given GPU address
 | ||||||
|  |     [[nodiscard]] size_t BytesToMapEnd(GPUVAddr gpu_addr) const noexcept; | ||||||
|  | 
 | ||||||
|     /**
 |     /**
 | ||||||
|      * ReadBlock and WriteBlock are full read and write operations over virtual |      * ReadBlock and WriteBlock are full read and write operations over virtual | ||||||
|      * GPU Memory. It's important to use these when GPU memory may not be continuous |      * GPU Memory. It's important to use these when GPU memory may not be continuous | ||||||
|  | @ -151,6 +154,9 @@ private: | ||||||
|     VideoCore::RasterizerInterface* rasterizer = nullptr; |     VideoCore::RasterizerInterface* rasterizer = nullptr; | ||||||
| 
 | 
 | ||||||
|     std::vector<PageEntry> page_table; |     std::vector<PageEntry> page_table; | ||||||
|  | 
 | ||||||
|  |     using MapRange = std::pair<GPUVAddr, size_t>; | ||||||
|  |     std::vector<MapRange> map_ranges; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace Tegra
 | } // namespace Tegra
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 bunnei
						bunnei