diff options
Diffstat (limited to 'src/core/memory.cpp')
| -rw-r--r-- | src/core/memory.cpp | 53 |
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. |
| 46 | struct Memory::Impl { | 46 | struct 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 | ||