diff options
| author | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 01:26:52 -0400 |
|---|---|---|
| committer | Takoroka <137927095+Takoroka@users.noreply.github.com> | 2026-10-29 01:26:52 -0400 |
| commit | c01459347405591446d50858d7b075d617a58be9 (patch) | |
| tree | e2b31109ab0ee66ca4b12612619bdeab03506be9 /src/video_core/memory_manager.cpp | |
| parent | e8bc734d1040044abe117a369a9f80a792e51df4 (diff) | |
video_core: cheaper small GPU reads, buffer usage tracking and compute uniforms
- MemoryManager::ReadBlockUnsafe reads within one 4 KiB page through a
single translation (as Read<T> does) instead of the page walk:
texture and sampler descriptors, several per draw (2.6% -> 0.1% of
title 1's GPU thread).
- UsageTracker skips ranges it tracked just before (until Reset): draws
bind the same multi-megabyte storage buffers again and again, and
each Track wrote a word per 4 KiB (2.0% -> 0.7%).
- Small compute uniform buffers the GPU has not written are streamed,
as graphics ones are; synchronizing them re-protected pages an inline
upload had just unprotected, two VirtualProtect calls per dispatch
(1.9% -> 0.7%, page protection 3.2% -> 2.3%).
Diffstat (limited to 'src/video_core/memory_manager.cpp')
| -rw-r--r-- | src/video_core/memory_manager.cpp | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 9a9fdab7bc..0eae8fac24 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -410,6 +410,16 @@ void MemoryManager::ReadBlock(GPUVAddr gpu_src_addr, void* dest_buffer, std::siz } void MemoryManager::ReadBlockUnsafe(GPUVAddr gpu_src_addr, void* dest_buffer, const std::size_t size) const { + // Small reads within one 4 KiB page (texture and sampler descriptors, several per draw): one + // translation and a copy, as Read<T> does, instead of the page walk (~3% of the GPU thread + // in title 1). Anything else, unmapped or sparse pages included, takes the full path. + constexpr std::size_t SmallPage = 0x1000; + if (size <= SmallPage && (gpu_src_addr & (SmallPage - 1)) + size <= SmallPage) { + if (const u8* const pointer = GetPointer(gpu_src_addr)) { + std::memcpy(dest_buffer, pointer, size); + return; + } + } ReadBlockImpl(gpu_src_addr, dest_buffer, size, VideoCommon::CacheType::None, true); } |
