diff options
| author | lizzie <lizzie@eden-emu.dev> | 2026-03-08 22:45:38 +0100 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-03-08 22:45:38 +0100 |
| commit | 6693b99ae44209b8e10ecc8b09517ceae9ab0bc0 (patch) | |
| tree | 97238dffbaa6e6ed15ab59ae278394bfe63c8057 /src/core/device_memory_manager.inc | |
| parent | f8ea09fa0f06572b32df1ead2fb38a64098e312e (diff) | |
[core] coalesce tracking entries for GPU (#3677)
I think I may have attempted this before, but I doubt it.
Anyways this should reduce virtual buffers from 3 to just 1, also improved access times :)
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3677
Reviewed-by: crueter <crueter@eden-emu.dev>
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/core/device_memory_manager.inc')
| -rw-r--r-- | src/core/device_memory_manager.inc | 79 |
1 files changed, 31 insertions, 48 deletions
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 08fe799174..15e3a1ad52 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc @@ -166,29 +166,21 @@ struct DeviceMemoryManagerAllocator { template <typename Traits> DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memory_) - : physical_base{reinterpret_cast<const uintptr_t>(device_memory_.buffer.BackingBasePointer())}, - device_inter{nullptr}, compressed_physical_ptr(device_as_size >> Memory::YUZU_PAGEBITS), - compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == - Settings::MemoryLayout::Memory_4Gb - ? physical_min_bits - : physical_max_bits) - - Memory::YUZU_PAGEBITS)), - continuity_tracker(device_as_size >> Memory::YUZU_PAGEBITS), - cpu_backing_address(device_as_size >> Memory::YUZU_PAGEBITS) { + : physical_base{uintptr_t(device_memory_.buffer.BackingBasePointer())} + , device_inter{nullptr} + , compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits : physical_max_bits) - Memory::YUZU_PAGEBITS)) + , tracked_entries(device_as_size >> Memory::YUZU_PAGEBITS) +{ impl = std::make_unique<DeviceMemoryManagerAllocator<Traits>>(); cached_pages = std::make_unique<CachedPages>(); const size_t total_virtual = device_as_size >> Memory::YUZU_PAGEBITS; for (size_t i = 0; i < total_virtual; i++) { - compressed_physical_ptr[i] = 0; - continuity_tracker[i] = 1; - cpu_backing_address[i] = 0; + tracked_entries[i].compressed_physical_ptr = 0; + tracked_entries[i].continuity_tracker = 1; + tracked_entries[i].cpu_backing_address = 0; } - const size_t total_phys = 1ULL << ((Settings::values.memory_layout_mode.GetValue() == - Settings::MemoryLayout::Memory_4Gb - ? physical_min_bits - : physical_max_bits) - - Memory::YUZU_PAGEBITS); + const size_t total_phys = 1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits : physical_max_bits) - Memory::YUZU_PAGEBITS); for (size_t i = 0; i < total_phys; i++) { compressed_device_addr[i] = 0; } @@ -228,11 +220,11 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size const VAddr new_vaddress = virtual_address + i * Memory::YUZU_PAGESIZE; auto* ptr = process_memory->GetPointerSilent(Common::ProcessAddress(new_vaddress)); if (ptr == nullptr) [[unlikely]] { - compressed_physical_ptr[start_page_d + i] = 0; + tracked_entries[start_page_d + i].compressed_physical_ptr = 0; continue; } auto phys_addr = static_cast<u32>(GetRawPhysicalAddr(ptr) >> Memory::YUZU_PAGEBITS) + 1U; - compressed_physical_ptr[start_page_d + i] = phys_addr; + tracked_entries[start_page_d + i].compressed_physical_ptr = phys_addr; InsertCPUBacking(start_page_d + i, new_vaddress, asid); const u32 base_dev = compressed_device_addr[phys_addr - 1U]; const u32 new_dev = static_cast<u32>(start_page_d + i); @@ -260,9 +252,9 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) { device_inter->InvalidateRegion(address, size); std::scoped_lock lk(mapping_guard); for (size_t i = 0; i < num_pages; i++) { - auto phys_addr = compressed_physical_ptr[start_page_d + i]; - compressed_physical_ptr[start_page_d + i] = 0; - cpu_backing_address[start_page_d + i] = 0; + auto phys_addr = tracked_entries[start_page_d + i].compressed_physical_ptr; + tracked_entries[start_page_d + i].compressed_physical_ptr = 0; + tracked_entries[start_page_d + i].cpu_backing_address = 0; if (phys_addr != 0) [[likely]] { const u32 base_dev = compressed_device_addr[phys_addr - 1U]; if ((base_dev >> MULTI_FLAG_BITS) == 0) [[likely]] { @@ -300,14 +292,14 @@ void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtu page_count = 1; } last_ptr = new_ptr; - continuity_tracker[start_page_d + index] = static_cast<u32>(page_count); + tracked_entries[start_page_d + index].continuity_tracker = static_cast<u32>(page_count); } } template <typename Traits> u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) { size_t page_index = src_addr >> page_bits; size_t subbits = src_addr & page_mask; - if ((static_cast<size_t>(continuity_tracker[page_index]) << page_bits) >= size + subbits) { + if ((static_cast<size_t>(tracked_entries[page_index].continuity_tracker) << page_bits) >= size + subbits) { return GetPointer<u8>(src_addr); } return nullptr; @@ -317,7 +309,7 @@ template <typename Traits> const u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) const { size_t page_index = src_addr >> page_bits; size_t subbits = src_addr & page_mask; - if ((static_cast<size_t>(continuity_tracker[page_index]) << page_bits) >= size + subbits) { + if ((static_cast<size_t>(tracked_entries[page_index].continuity_tracker) << page_bits) >= size + subbits) { return GetPointer<u8>(src_addr); } return nullptr; @@ -342,12 +334,10 @@ template <typename T> T* DeviceMemoryManager<Traits>::GetPointer(DAddr address) { const size_t index = address >> Memory::YUZU_PAGEBITS; const size_t offset = address & Memory::YUZU_PAGEMASK; - auto phys_addr = compressed_physical_ptr[index]; - if (phys_addr == 0) [[unlikely]] { + auto phys_addr = tracked_entries[index].compressed_physical_ptr; + if (phys_addr == 0) [[unlikely]] return nullptr; - } - return GetPointerFromRaw<T>((static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) + - offset); + return GetPointerFromRaw<T>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS) + offset); } template <typename Traits> @@ -355,12 +345,10 @@ template <typename T> const T* DeviceMemoryManager<Traits>::GetPointer(DAddr address) const { const size_t index = address >> Memory::YUZU_PAGEBITS; const size_t offset = address & Memory::YUZU_PAGEMASK; - auto phys_addr = compressed_physical_ptr[index]; - if (phys_addr == 0) [[unlikely]] { + auto phys_addr = tracked_entries[index].compressed_physical_ptr; + if (phys_addr == 0) return nullptr; - } - return GetPointerFromRaw<T>((static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) + - offset); + return GetPointerFromRaw<T>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS) + offset); } template <typename Traits> @@ -386,18 +374,14 @@ T DeviceMemoryManager<Traits>::Read(DAddr address) const { } template <typename Traits> -void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto on_unmapped, - auto on_memory, auto increment) { +void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto on_unmapped, auto on_memory, auto increment) { std::size_t remaining_size = size; std::size_t page_index = addr >> Memory::YUZU_PAGEBITS; std::size_t page_offset = addr & Memory::YUZU_PAGEMASK; - while (remaining_size) { - const size_t next_pages = static_cast<std::size_t>(continuity_tracker[page_index]); - const std::size_t copy_amount = - (std::min)((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size); - const auto current_vaddr = - static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset); + const size_t next_pages = std::size_t(tracked_entries[page_index].continuity_tracker); + const std::size_t copy_amount = (std::min)((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size); + const auto current_vaddr = u64((page_index << Memory::YUZU_PAGEBITS) + page_offset); SCOPE_EXIT{ page_index += next_pages; page_offset = 0; @@ -405,13 +389,12 @@ void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto o remaining_size -= copy_amount; }; - auto phys_addr = compressed_physical_ptr[page_index]; + auto phys_addr = tracked_entries[page_index].compressed_physical_ptr; if (phys_addr == 0) { on_unmapped(copy_amount, current_vaddr); continue; } - auto* mem_ptr = GetPointerFromRaw<u8>( - (static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS) + page_offset); + auto* mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS) + page_offset); on_memory(copy_amount, mem_ptr); } } @@ -430,7 +413,7 @@ void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, s } const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; - const auto phys_addr = compressed_physical_ptr[page_index]; + const auto phys_addr = tracked_entries[page_index].compressed_physical_ptr; if (phys_addr != 0) { auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS)); t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; @@ -488,7 +471,7 @@ void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_poin } const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; - const auto phys_addr = compressed_physical_ptr[page_index]; + const auto phys_addr = tracked_entries[page_index].compressed_physical_ptr; if (phys_addr != 0) { auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS)); t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr}; |
