summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
authorGravatar Ameer J2023-11-26 21:08:53 -0500
committerGravatar GitHub2023-11-26 21:08:53 -0500
commit1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a (patch)
treec219aacab776c0a1e3956614b60a01fa2f6164cb /src/core/memory.cpp
parentshader_recompiler: Align SSBO offsets in GlobalMemory functions (diff)
parentMerge pull request #11535 from GPUCode/upload_cmdbuf (diff)
downloadyuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.gz
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.tar.xz
yuzu-1d11fe00a3000efbf6a0a4bb690e0d544a1b7b4a.zip
Merge branch 'master' into ssbo-align
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp31
1 files changed, 23 insertions, 8 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index fa5273402..a3431772a 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -1,8 +1,10 @@
1// SPDX-FileCopyrightText: 2015 Citra Emulator Project 1// SPDX-FileCopyrightText: 2015 Citra Emulator Project
2// SPDX-FileCopyrightText: 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 3// SPDX-License-Identifier: GPL-2.0-or-later
3 4
4#include <algorithm> 5#include <algorithm>
5#include <cstring> 6#include <cstring>
7#include <mutex>
6#include <span> 8#include <span>
7 9
8#include "common/assert.h" 10#include "common/assert.h"
@@ -10,6 +12,7 @@
10#include "common/common_types.h" 12#include "common/common_types.h"
11#include "common/logging/log.h" 13#include "common/logging/log.h"
12#include "common/page_table.h" 14#include "common/page_table.h"
15#include "common/scope_exit.h"
13#include "common/settings.h" 16#include "common/settings.h"
14#include "common/swap.h" 17#include "common/swap.h"
15#include "core/core.h" 18#include "core/core.h"
@@ -41,7 +44,7 @@ struct Memory::Impl {
41 explicit Impl(Core::System& system_) : system{system_} {} 44 explicit Impl(Core::System& system_) : system{system_} {}
42 45
43 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { 46 void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) {
44 current_page_table = &process.GetPageTable().PageTableImpl(); 47 current_page_table = &process.GetPageTable().GetImpl();
45 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer(); 48 current_page_table->fastmem_arena = system.DeviceMemory().buffer.VirtualBasePointer();
46 49
47 const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth(); 50 const std::size_t address_space_width = process.GetPageTable().GetAddressSpaceWidth();
@@ -195,7 +198,7 @@ struct Memory::Impl {
195 198
196 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped, 199 bool WalkBlock(const Common::ProcessAddress addr, const std::size_t size, auto on_unmapped,
197 auto on_memory, auto on_rasterizer, auto increment) { 200 auto on_memory, auto on_rasterizer, auto increment) {
198 const auto& page_table = system.ApplicationProcess()->GetPageTable().PageTableImpl(); 201 const auto& page_table = system.ApplicationProcess()->GetPageTable().GetImpl();
199 std::size_t remaining_size = size; 202 std::size_t remaining_size = size;
200 std::size_t page_index = addr >> YUZU_PAGEBITS; 203 std::size_t page_index = addr >> YUZU_PAGEBITS;
201 std::size_t page_offset = addr & YUZU_PAGEMASK; 204 std::size_t page_offset = addr & YUZU_PAGEMASK;
@@ -318,7 +321,7 @@ struct Memory::Impl {
318 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, 321 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
319 u8* const host_ptr) { 322 u8* const host_ptr) {
320 if constexpr (!UNSAFE) { 323 if constexpr (!UNSAFE) {
321 system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); 324 HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
322 } 325 }
323 std::memcpy(host_ptr, src_buffer, copy_amount); 326 std::memcpy(host_ptr, src_buffer, copy_amount);
324 }, 327 },
@@ -351,7 +354,7 @@ struct Memory::Impl {
351 }, 354 },
352 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount, 355 [&](const Common::ProcessAddress current_vaddr, const std::size_t copy_amount,
353 u8* const host_ptr) { 356 u8* const host_ptr) {
354 system.GPU().InvalidateRegion(GetInteger(current_vaddr), copy_amount); 357 HandleRasterizerWrite(GetInteger(current_vaddr), copy_amount);
355 std::memset(host_ptr, 0, copy_amount); 358 std::memset(host_ptr, 0, copy_amount);
356 }, 359 },
357 [](const std::size_t copy_amount) {}); 360 [](const std::size_t copy_amount) {});
@@ -420,7 +423,7 @@ struct Memory::Impl {
420 const std::size_t block_size) { 423 const std::size_t block_size) {
421 // dc cvac: Store to point of coherency 424 // dc cvac: Store to point of coherency
422 // CPU flush -> GPU invalidate 425 // CPU flush -> GPU invalidate
423 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 426 HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
424 }; 427 };
425 return PerformCacheOperation(dest_addr, size, on_rasterizer); 428 return PerformCacheOperation(dest_addr, size, on_rasterizer);
426 } 429 }
@@ -430,7 +433,7 @@ struct Memory::Impl {
430 const std::size_t block_size) { 433 const std::size_t block_size) {
431 // dc civac: Store to point of coherency, and invalidate from cache 434 // dc civac: Store to point of coherency, and invalidate from cache
432 // CPU flush -> GPU invalidate 435 // CPU flush -> GPU invalidate
433 system.GPU().InvalidateRegion(GetInteger(current_vaddr), block_size); 436 HandleRasterizerWrite(GetInteger(current_vaddr), block_size);
434 }; 437 };
435 return PerformCacheOperation(dest_addr, size, on_rasterizer); 438 return PerformCacheOperation(dest_addr, size, on_rasterizer);
436 } 439 }
@@ -767,7 +770,18 @@ struct Memory::Impl {
767 } 770 }
768 771
769 void HandleRasterizerWrite(VAddr address, size_t size) { 772 void HandleRasterizerWrite(VAddr address, size_t size) {
770 const size_t core = system.GetCurrentHostThreadID(); 773 constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
774 const size_t core = std::min(system.GetCurrentHostThreadID(),
775 sys_core); // any other calls threads go to syscore.
776 // Guard on sys_core;
777 if (core == sys_core) [[unlikely]] {
778 sys_core_guard.lock();
779 }
780 SCOPE_EXIT({
781 if (core == sys_core) [[unlikely]] {
782 sys_core_guard.unlock();
783 }
784 });
771 auto& current_area = rasterizer_write_areas[core]; 785 auto& current_area = rasterizer_write_areas[core];
772 VAddr subaddress = address >> YUZU_PAGEBITS; 786 VAddr subaddress = address >> YUZU_PAGEBITS;
773 bool do_collection = current_area.last_address == subaddress; 787 bool do_collection = current_area.last_address == subaddress;
@@ -799,6 +813,7 @@ struct Memory::Impl {
799 rasterizer_read_areas{}; 813 rasterizer_read_areas{};
800 std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{}; 814 std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
801 std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers; 815 std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
816 std::mutex sys_core_guard;
802}; 817};
803 818
804Memory::Memory(Core::System& system_) : system{system_} { 819Memory::Memory(Core::System& system_) : system{system_} {
@@ -826,7 +841,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress b
826 841
827bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const { 842bool Memory::IsValidVirtualAddress(const Common::ProcessAddress vaddr) const {
828 const Kernel::KProcess& process = *system.ApplicationProcess(); 843 const Kernel::KProcess& process = *system.ApplicationProcess();
829 const auto& page_table = process.GetPageTable().PageTableImpl(); 844 const auto& page_table = process.GetPageTable().GetImpl();
830 const size_t page = vaddr >> YUZU_PAGEBITS; 845 const size_t page = vaddr >> YUZU_PAGEBITS;
831 if (page >= page_table.pointers.size()) { 846 if (page >= page_table.pointers.size()) {
832 return false; 847 return false;