summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2023-12-30 09:37:16 +0100
committerGravatar Liam2024-01-18 21:12:30 -0500
commitd8f1ce2f7640200d92a12698c42029316ac1a611 (patch)
tree34c983ea5d60c58f0511f993090b70aebe778582 /src
parentSMMU: Simplify and remove old code. (diff)
downloadyuzu-d8f1ce2f7640200d92a12698c42029316ac1a611.tar.gz
yuzu-d8f1ce2f7640200d92a12698c42029316ac1a611.tar.xz
yuzu-d8f1ce2f7640200d92a12698c42029316ac1a611.zip
SMMU: Add continuity tracking optimization.
Diffstat (limited to 'src')
-rw-r--r--src/core/device_memory_manager.h21
-rw-r--r--src/core/device_memory_manager.inc52
-rw-r--r--src/core/hle/service/nvdrv/core/container.cpp1
-rw-r--r--src/core/hle/service/nvdrv/core/nvmap.cpp2
4 files changed, 63 insertions, 13 deletions
diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h
index 0273b78db..0f6599cfe 100644
--- a/src/core/device_memory_manager.h
+++ b/src/core/device_memory_manager.h
@@ -13,7 +13,6 @@
13#include "common/scratch_buffer.h" 13#include "common/scratch_buffer.h"
14#include "common/virtual_buffer.h" 14#include "common/virtual_buffer.h"
15 15
16
17namespace Core { 16namespace Core {
18 17
19class DeviceMemory; 18class DeviceMemory;
@@ -40,9 +39,17 @@ public:
40 void AllocateFixed(DAddr start, size_t size); 39 void AllocateFixed(DAddr start, size_t size);
41 void Free(DAddr start, size_t size); 40 void Free(DAddr start, size_t size);
42 41
43 void Map(DAddr address, VAddr virtual_address, size_t size, size_t process_id); 42 void Map(DAddr address, VAddr virtual_address, size_t size, size_t process_id,
43 bool track = false);
44
44 void Unmap(DAddr address, size_t size); 45 void Unmap(DAddr address, size_t size);
45 46
47 void TrackContinuityImpl(DAddr address, VAddr virtual_address, size_t size, size_t process_id);
48 void TrackContinuity(DAddr address, VAddr virtual_address, size_t size, size_t process_id) {
49 std::scoped_lock lk(mapping_guard);
50 TrackContinuityImpl(address, virtual_address, size, process_id);
51 }
52
46 // Write / Read 53 // Write / Read
47 template <typename T> 54 template <typename T>
48 T* GetPointer(DAddr address); 55 T* GetPointer(DAddr address);
@@ -86,13 +93,8 @@ public:
86 template <typename T> 93 template <typename T>
87 T Read(DAddr address) const; 94 T Read(DAddr address) const;
88 95
89 const u8* GetSpan(const DAddr src_addr, const std::size_t size) const { 96 u8* GetSpan(const DAddr src_addr, const std::size_t size);
90 return nullptr; 97 const u8* GetSpan(const DAddr src_addr, const std::size_t size) const;
91 }
92
93 u8* GetSpan(const DAddr src_addr, const std::size_t size) {
94 return nullptr;
95 }
96 98
97 void ReadBlock(DAddr address, void* dest_pointer, size_t size); 99 void ReadBlock(DAddr address, void* dest_pointer, size_t size);
98 void ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size); 100 void ReadBlockUnsafe(DAddr address, void* dest_pointer, size_t size);
@@ -144,6 +146,7 @@ private:
144 DeviceInterface* interface; 146 DeviceInterface* interface;
145 Common::VirtualBuffer<u32> compressed_physical_ptr; 147 Common::VirtualBuffer<u32> compressed_physical_ptr;
146 Common::VirtualBuffer<u32> compressed_device_addr; 148 Common::VirtualBuffer<u32> compressed_device_addr;
149 Common::VirtualBuffer<u32> continuity_tracker;
147 150
148 // Process memory interfaces 151 // Process memory interfaces
149 152
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc
index e9d0efe19..175f0cd5f 100644
--- a/src/core/device_memory_manager.inc
+++ b/src/core/device_memory_manager.inc
@@ -164,6 +164,7 @@ DeviceMemoryManager<Traits>::DeviceMemoryManager(const DeviceMemory& device_memo
164 : physical_base{reinterpret_cast<const uintptr_t>(device_memory_.buffer.BackingBasePointer())}, 164 : physical_base{reinterpret_cast<const uintptr_t>(device_memory_.buffer.BackingBasePointer())},
165 interface{nullptr}, compressed_physical_ptr(device_as_size >> Memory::YUZU_PAGEBITS), 165 interface{nullptr}, compressed_physical_ptr(device_as_size >> Memory::YUZU_PAGEBITS),
166 compressed_device_addr(1ULL << (physical_max_bits - Memory::YUZU_PAGEBITS)), 166 compressed_device_addr(1ULL << (physical_max_bits - Memory::YUZU_PAGEBITS)),
167 continuity_tracker(device_as_size >> Memory::YUZU_PAGEBITS),
167 cpu_backing_address(device_as_size >> Memory::YUZU_PAGEBITS) { 168 cpu_backing_address(device_as_size >> Memory::YUZU_PAGEBITS) {
168 impl = std::make_unique<DeviceMemoryManagerAllocator<Traits>>(); 169 impl = std::make_unique<DeviceMemoryManagerAllocator<Traits>>();
169 cached_pages = std::make_unique<CachedPages>(); 170 cached_pages = std::make_unique<CachedPages>();
@@ -194,7 +195,7 @@ void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) {
194 195
195template <typename Traits> 196template <typename Traits>
196void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, 197void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size,
197 size_t process_id) { 198 size_t process_id, bool track) {
198 Core::Memory::Memory* process_memory = registered_processes[process_id]; 199 Core::Memory::Memory* process_memory = registered_processes[process_id];
199 size_t start_page_d = address >> Memory::YUZU_PAGEBITS; 200 size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
200 size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS; 201 size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
@@ -222,6 +223,9 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size
222 } 223 }
223 impl->multi_dev_address.Register(new_dev, start_id); 224 impl->multi_dev_address.Register(new_dev, start_id);
224 } 225 }
226 if (track) {
227 TrackContinuityImpl(address, virtual_address, size, process_id);
228 }
225} 229}
226 230
227template <typename Traits> 231template <typename Traits>
@@ -251,6 +255,47 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) {
251 } 255 }
252 } 256 }
253} 257}
258template <typename Traits>
259void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
260 size_t size, size_t process_id) {
261 Core::Memory::Memory* process_memory = registered_processes[process_id];
262 size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
263 size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
264 uintptr_t last_ptr = 0;
265 size_t page_count = 1;
266 for (size_t i = num_pages; i > 0; i--) {
267 size_t index = i - 1;
268 const VAddr new_vaddress = virtual_address + index * Memory::YUZU_PAGESIZE;
269 const uintptr_t new_ptr = reinterpret_cast<uintptr_t>(
270 process_memory->GetPointerSilent(Common::ProcessAddress(new_vaddress)));
271 if (new_ptr + page_size == last_ptr) {
272 page_count++;
273 } else {
274 page_count = 1;
275 }
276 last_ptr = new_ptr;
277 continuity_tracker[start_page_d + index] = static_cast<u32>(page_count);
278 }
279}
280template <typename Traits>
281u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) {
282 size_t page_index = src_addr >> page_bits;
283 size_t subbits = src_addr & page_mask;
284 if ((continuity_tracker[page_index] << page_bits) >= size + subbits) {
285 return GetPointer<u8>(src_addr);
286 }
287 return nullptr;
288}
289
290template <typename Traits>
291const u8* DeviceMemoryManager<Traits>::GetSpan(const DAddr src_addr, const std::size_t size) const {
292 size_t page_index = src_addr >> page_bits;
293 size_t subbits = src_addr & page_mask;
294 if ((continuity_tracker[page_index] << page_bits) >= size + subbits) {
295 return GetPointer<u8>(src_addr);
296 }
297 return nullptr;
298}
254 299
255template <typename Traits> 300template <typename Traits>
256void DeviceMemoryManager<Traits>::InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer, 301void DeviceMemoryManager<Traits>::InnerGatherDeviceAddresses(Common::ScratchBuffer<u32>& buffer,
@@ -322,12 +367,13 @@ void DeviceMemoryManager<Traits>::WalkBlock(DAddr addr, std::size_t size, auto o
322 std::size_t page_offset = addr & Memory::YUZU_PAGEMASK; 367 std::size_t page_offset = addr & Memory::YUZU_PAGEMASK;
323 368
324 while (remaining_size) { 369 while (remaining_size) {
370 const size_t next_pages = static_cast<std::size_t>(continuity_tracker[page_index]);
325 const std::size_t copy_amount = 371 const std::size_t copy_amount =
326 std::min(static_cast<std::size_t>(Memory::YUZU_PAGESIZE) - page_offset, remaining_size); 372 std::min((next_pages << Memory::YUZU_PAGEBITS) - page_offset, remaining_size);
327 const auto current_vaddr = 373 const auto current_vaddr =
328 static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset); 374 static_cast<u64>((page_index << Memory::YUZU_PAGEBITS) + page_offset);
329 SCOPE_EXIT({ 375 SCOPE_EXIT({
330 page_index++; 376 page_index += next_pages;
331 page_offset = 0; 377 page_offset = 0;
332 increment(copy_amount); 378 increment(copy_amount);
333 remaining_size -= copy_amount; 379 remaining_size -= copy_amount;
diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp
index ba7eb9e24..4d3a9d696 100644
--- a/src/core/hle/service/nvdrv/core/container.cpp
+++ b/src/core/hle/service/nvdrv/core/container.cpp
@@ -95,6 +95,7 @@ size_t Container::OpenSession(Kernel::KProcess* process) {
95 if (start_region != 0) { 95 if (start_region != 0) {
96 session.mapper = std::make_unique<HeapMapper>(region_start, start_region, region_size, 96 session.mapper = std::make_unique<HeapMapper>(region_start, start_region, region_size,
97 smmu_id, impl->host1x); 97 smmu_id, impl->host1x);
98 smmu.TrackContinuity(start_region, region_start, region_size, smmu_id);
98 session.has_preallocated_area = true; 99 session.has_preallocated_area = true;
99 LOG_CRITICAL(Debug, "Preallocation created!"); 100 LOG_CRITICAL(Debug, "Preallocation created!");
100 } 101 }
diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp
index 023c070d9..97634b59d 100644
--- a/src/core/hle/service/nvdrv/core/nvmap.cpp
+++ b/src/core/hle/service/nvdrv/core/nvmap.cpp
@@ -221,7 +221,7 @@ DAddr NvMap::PinHandle(NvMap::Handle::Id handle, size_t session_id, bool low_are
221 } 221 }
222 222
223 handle_description->d_address = address; 223 handle_description->d_address = address;
224 smmu.Map(address, vaddress, map_size, session->smmu_id); 224 smmu.Map(address, vaddress, map_size, session->smmu_id, true);
225 handle_description->in_heap = false; 225 handle_description->in_heap = false;
226 } 226 }
227 } 227 }