diff options
| author | lizzie <lizzie@eden-emu.dev> | 2025-07-13 03:40:48 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2025-07-13 03:40:48 +0200 |
| commit | 5091759a47182fd85e12ca58abcb57d6f4ca1ea1 (patch) | |
| tree | bc9aa9de346c4a24b6b7aafca73462e5905d2ad4 /src/core/memory.cpp | |
| parent | 03351a4f8b463a798d64dcb78899b4cdd9004071 (diff) | |
[vk, opengl] defer checks to topmost call (avoid unnecessary call) (#40)
Co-authored-by: crueter <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/40
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp index b033858bf8..34539cc650 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2015 Citra Emulator Project // SPDX-FileCopyrightText: 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -868,35 +871,35 @@ struct Memory::Impl { [[nodiscard]] u8* GetPointerImpl(u64 vaddr, auto on_unmapped, auto on_rasterizer) const { // AARCH64 masks the upper 16 bit of all memory accesses vaddr = vaddr & 0xffffffffffffULL; - if (!AddressSpaceContains(*current_page_table, vaddr, 1)) [[unlikely]] { on_unmapped(); return nullptr; + } else { + // Avoid adding any extra logic to this fast-path block + const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); + if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { + return reinterpret_cast<u8*>(pointer + vaddr); + } else { + switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { + case Common::PageType::Unmapped: + on_unmapped(); + return nullptr; + case Common::PageType::Memory: + ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr); + return nullptr; + case Common::PageType::DebugMemory: + return GetPointerFromDebugMemory(vaddr); + case Common::PageType::RasterizerCachedMemory: { + u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; + on_rasterizer(); + return host_ptr; + } + default: + UNREACHABLE(); + } + return nullptr; + } } - - // Avoid adding any extra logic to this fast-path block - const uintptr_t raw_pointer = current_page_table->pointers[vaddr >> YUZU_PAGEBITS].Raw(); - if (const uintptr_t pointer = Common::PageTable::PageInfo::ExtractPointer(raw_pointer)) { - return reinterpret_cast<u8*>(pointer + vaddr); - } - switch (Common::PageTable::PageInfo::ExtractType(raw_pointer)) { - case Common::PageType::Unmapped: - on_unmapped(); - return nullptr; - case Common::PageType::Memory: - ASSERT_MSG(false, "Mapped memory page without a pointer @ 0x{:016X}", vaddr); - return nullptr; - case Common::PageType::DebugMemory: - return GetPointerFromDebugMemory(vaddr); - case Common::PageType::RasterizerCachedMemory: { - u8* const host_ptr{GetPointerFromRasterizerCachedMemory(vaddr)}; - on_rasterizer(); - return host_ptr; - } - default: - UNREACHABLE(); - } - return nullptr; } [[nodiscard]] u8* GetPointer(const Common::ProcessAddress vaddr) const { @@ -1149,13 +1152,19 @@ struct Memory::Impl { gpu_device_memory->ApplyOpOnPointer(p, scratch_buffers[core], [&](DAddr address) { auto& current_area = rasterizer_write_areas[core]; PAddr subaddress = address >> YUZU_PAGEBITS; - bool do_collection = current_area.last_address == subaddress; - if (!do_collection) [[unlikely]] { - do_collection = system.GPU().OnCPUWrite(address, size); - if (!do_collection) { + // Performance note: + // It may not be a good idea to assume accesses are within the same subaddress (i.e same page) + // It is often the case the games like to access wildly different addresses. Hence why I propose + // we should let the compiler just do it's thing... + if (current_area.last_address != subaddress) { + // Short circuit the need to check for address/size + auto const do_collection = (address != 0 && size != 0) + && system.GPU().OnCPUWrite(address, size); + if (do_collection) { + current_area.last_address = subaddress; + } else { return; } - current_area.last_address = subaddress; } gpu_dirty_managers[core].Collect(address, size); }); |
