diff options
Diffstat (limited to 'src/core/device_memory_manager.inc')
| -rw-r--r-- | src/core/device_memory_manager.inc | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 4be26d9631..08fe799174 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project @@ -247,6 +247,7 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size } impl->multi_dev_address.Register(new_dev, start_id); } + t_slot = {}; if (track) { TrackContinuityImpl(address, virtual_address, size, asid); } @@ -278,6 +279,7 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) { compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG; } } + t_slot = {}; } template <typename Traits> void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address, @@ -417,6 +419,26 @@ void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto o template <typename Traits> void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, size_t size) { device_inter->FlushRegion(address, size); + const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; + if (size <= Memory::YUZU_PAGESIZE - page_offset) { + const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); + for (size_t i = 0; i < 4; ++i) { + if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) { + std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size); + return; + } + } + + const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; + const auto phys_addr = compressed_physical_ptr[page_index]; + 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}; + cache_cursor = (cache_cursor + 1) & 3U; + std::memcpy(dest_pointer, mem_ptr + page_offset, size); + return; + } + } WalkBlock( address, size, [&](size_t copy_amount, DAddr current_vaddr) { @@ -455,6 +477,26 @@ void DeviceMemoryManager<Traits>::WriteBlock(DAddr address, const void* src_poin template <typename Traits> void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size) { + const std::size_t page_offset = address & Memory::YUZU_PAGEMASK; + if (size <= Memory::YUZU_PAGESIZE - page_offset) { + const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK); + for (size_t i = 0; i < 4; ++i) { + if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) { + std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size); + return; + } + } + + const std::size_t page_index = address >> Memory::YUZU_PAGEBITS; + const auto phys_addr = compressed_physical_ptr[page_index]; + 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}; + cache_cursor = (cache_cursor + 1) & 3U; + std::memcpy(dest_pointer, mem_ptr + page_offset, size); + return; + } + } WalkBlock( address, size, [&](size_t copy_amount, DAddr current_vaddr) { |
