summaryrefslogtreecommitdiff
path: root/src/core/memory.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/memory.cpp')
-rw-r--r--src/core/memory.cpp53
1 files changed, 32 insertions, 21 deletions
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 609e775ae..f126840cb 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -44,7 +44,8 @@ bool AddressSpaceContains(const Common::PageTable& table, const Common::ProcessA
44// from outside classes. This also allows modification to the internals of the memory 44// from outside classes. This also allows modification to the internals of the memory
45// subsystem without needing to rebuild all files that make use of the memory interface. 45// subsystem without needing to rebuild all files that make use of the memory interface.
46struct Memory::Impl { 46struct Memory::Impl {
47 explicit Impl(Core::System& system_) : system{system_} {} 47 explicit Impl(Core::System& system_)
48 : system{system_} {}
48 49
49 void SetCurrentPageTable(Kernel::KProcess& process) { 50 void SetCurrentPageTable(Kernel::KProcess& process) {
50 current_page_table = &process.GetPageTable().GetImpl(); 51 current_page_table = &process.GetPageTable().GetImpl();
@@ -817,26 +818,31 @@ struct Memory::Impl {
817 void HandleRasterizerDownload(VAddr v_address, size_t size) { 818 void HandleRasterizerDownload(VAddr v_address, size_t size) {
818 const auto* p = GetPointerImpl( 819 const auto* p = GetPointerImpl(
819 v_address, []() {}, []() {}); 820 v_address, []() {}, []() {});
820 auto& gpu_device_memory = system.Host1x().MemoryManager(); 821 if (!gpu_device_memory) [[unlikely]] {
821 DAddr address = 822 gpu_device_memory = &system.Host1x().MemoryManager();
822 gpu_device_memory.GetAddressFromPAddr(system.DeviceMemory().GetRawPhysicalAddr(p)); 823 }
823 const size_t core = system.GetCurrentHostThreadID(); 824 const size_t core = system.GetCurrentHostThreadID();
824 auto& current_area = rasterizer_read_areas[core]; 825 auto& current_area = rasterizer_read_areas[core];
825 const DAddr end_address = address + size; 826 gpu_device_memory->ApplyOpOnPointer(
826 if (current_area.start_address <= address && end_address <= current_area.end_address) 827 p, scratch_buffers[core], [&](DAddr address) {
827 [[likely]] { 828 const DAddr end_address = address + size;
828 return; 829 if (current_area.start_address <= address && end_address <= current_area.end_address)
829 } 830 [[likely]] {
830 current_area = system.GPU().OnCPURead(address, size); 831 return;
832 }
833 current_area = system.GPU().OnCPURead(address, size);
834 });
831 } 835 }
832 836
833 void HandleRasterizerWrite(VAddr v_address, size_t size) { 837 void HandleRasterizerWrite(VAddr v_address, size_t size) {
834 const auto* p = GetPointerImpl( 838 const auto* p = GetPointerImpl(
835 v_address, []() {}, []() {}); 839 v_address, []() {}, []() {});
836 PAddr address = system.DeviceMemory().GetRawPhysicalAddr(p);
837 constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1; 840 constexpr size_t sys_core = Core::Hardware::NUM_CPU_CORES - 1;
838 const size_t core = std::min(system.GetCurrentHostThreadID(), 841 const size_t core = std::min(system.GetCurrentHostThreadID(),
839 sys_core); // any other calls threads go to syscore. 842 sys_core); // any other calls threads go to syscore.
843 if (!gpu_device_memory) [[unlikely]] {
844 gpu_device_memory = &system.Host1x().MemoryManager();
845 }
840 // Guard on sys_core; 846 // Guard on sys_core;
841 if (core == sys_core) [[unlikely]] { 847 if (core == sys_core) [[unlikely]] {
842 sys_core_guard.lock(); 848 sys_core_guard.lock();
@@ -846,17 +852,20 @@ struct Memory::Impl {
846 sys_core_guard.unlock(); 852 sys_core_guard.unlock();
847 } 853 }
848 }); 854 });
849 auto& current_area = rasterizer_write_areas[core]; 855 gpu_device_memory->ApplyOpOnPointer(
850 PAddr subaddress = address >> YUZU_PAGEBITS; 856 p, scratch_buffers[core], [&](DAddr address) {
851 bool do_collection = current_area.last_address == subaddress; 857 auto& current_area = rasterizer_write_areas[core];
852 if (!do_collection) [[unlikely]] { 858 PAddr subaddress = address >> YUZU_PAGEBITS;
853 do_collection = system.GPU().OnCPUWrite(address, size); 859 bool do_collection = current_area.last_address == subaddress;
854 if (!do_collection) { 860 if (!do_collection) [[unlikely]] {
855 return; 861 do_collection = system.GPU().OnCPUWrite(address, size);
862 if (!do_collection) {
863 return;
864 }
865 current_area.last_address = subaddress;
856 } 866 }
857 current_area.last_address = subaddress; 867 gpu_dirty_managers[core].Collect(address, size);
858 } 868 });
859 gpu_dirty_managers[core].Collect(address, size);
860 } 869 }
861 870
862 struct GPUDirtyState { 871 struct GPUDirtyState {
@@ -872,10 +881,12 @@ struct Memory::Impl {
872 } 881 }
873 882
874 Core::System& system; 883 Core::System& system;
884 Tegra::MaxwellDeviceMemoryManager* gpu_device_memory{};
875 Common::PageTable* current_page_table = nullptr; 885 Common::PageTable* current_page_table = nullptr;
876 std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES> 886 std::array<VideoCore::RasterizerDownloadArea, Core::Hardware::NUM_CPU_CORES>
877 rasterizer_read_areas{}; 887 rasterizer_read_areas{};
878 std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{}; 888 std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
889 std::array<Common::ScratchBuffer<u32>, Core::Hardware::NUM_CPU_CORES> scratch_buffers{};
879 std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers; 890 std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
880 std::mutex sys_core_guard; 891 std::mutex sys_core_guard;
881 892