diff options
Diffstat (limited to 'src/video_core/memory_manager.cpp')
| -rw-r--r-- | src/video_core/memory_manager.cpp | 24 |
1 files changed, 14 insertions, 10 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 9111ba10d2..ddfd2529fd 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -302,7 +302,7 @@ void MemoryManager::Write(GPUVAddr addr, T data) { return; } // A Switch 2 sparse block nobody wrote yet gets its memory now. - Tegra::Nx2BackSparseWrite(addr, sizeof(T)); + Tegra::Nx2BackSparseWrite(addr, sizeof(T), &data); if (auto page_pointer{GetPointer(addr)}; page_pointer) { std::memcpy(page_pointer, &data, sizeof(T)); return; @@ -431,11 +431,14 @@ void MemoryManager::ReadBlockImpl(GPUVAddr gpu_src_addr, void* dest_buffer, std: if (!unsafe) { rasterizer->FlushRegion(dev_addr_base, copy_amount, which); } - if (!IsBigPageContinuous(page_index)) [[unlikely]] { - memory.ReadBlockUnsafe(dev_addr_base, dest_buffer, copy_amount); - } else { - u8* physical = memory.GetPointer<u8>(dev_addr_base); + // A continuous big page may still have no host memory (a Switch 2 region backed as it is + // written, while its backing is pending): the per-page copy handles that. + u8* const physical = IsBigPageContinuous(page_index) ? memory.GetPointer<u8>(dev_addr_base) + : nullptr; + if (physical != nullptr) [[likely]] { std::memcpy(dest_buffer, physical, copy_amount); + } else { + memory.ReadBlockUnsafe(dev_addr_base, dest_buffer, copy_amount); } dest_buffer = static_cast<u8*>(dest_buffer) + copy_amount; }; @@ -466,7 +469,7 @@ void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, co void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffer, std::size_t size, [[maybe_unused]] VideoCommon::CacheType which, bool unsafe) { // Give Switch 2 sparse pages the write lands on their memory first (otherwise it is dropped). - Tegra::Nx2BackSparseWrite(gpu_dest_addr, size); + Tegra::Nx2BackSparseWrite(gpu_dest_addr, size, src_buffer); auto just_advance = [&]([[maybe_unused]] std::size_t page_index, [[maybe_unused]] std::size_t offset, std::size_t copy_amount) { src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; }; @@ -485,11 +488,12 @@ void MemoryManager::WriteBlockImpl(GPUVAddr gpu_dest_addr, const void* src_buffe if (!unsafe) { rasterizer->InvalidateRegion(dev_addr_base, copy_amount, which); } - if (!IsBigPageContinuous(page_index)) [[unlikely]] { - memory.WriteBlockUnsafe(dev_addr_base, src_buffer, copy_amount); - } else { - u8* physical = memory.GetPointer<u8>(dev_addr_base); + u8* const physical = IsBigPageContinuous(page_index) ? memory.GetPointer<u8>(dev_addr_base) + : nullptr; + if (physical != nullptr) [[likely]] { std::memcpy(physical, src_buffer, copy_amount); + } else { + memory.WriteBlockUnsafe(dev_addr_base, src_buffer, copy_amount); } src_buffer = static_cast<const u8*>(src_buffer) + copy_amount; }; |
