From 4da373f2082f5e46e6163425abd1b23e5cad217d Mon Sep 17 00:00:00 2001 From: IndecisiveTurtle <47210458+raphaelthegreat@users.noreply.github.com> Date: Mon, 24 Feb 2025 11:26:32 +0200 Subject: [PATCH] memory: Improve buffer size clamping --- src/core/memory.cpp | 18 ++++++++++++++---- src/video_core/texture_cache/texture_cache.cpp | 4 ++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 017b77cdb..98d587e00 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -57,15 +57,25 @@ void MemoryManager::SetupMemoryRegions(u64 flexible_size, bool use_extended_mem1 } u64 MemoryManager::ClampRangeSize(VAddr virtual_addr, u64 size) { - static constexpr u64 MinSizeToClamp = 1_GB; + static constexpr u64 MinSizeToClamp = 512_MB; // Dont bother with clamping if the size is small so we dont pay a map lookup on every buffer. if (size < MinSizeToClamp) { return size; } - const auto vma = FindVMA(virtual_addr); + + // Clamp size to the remaining size of the current VMA. + auto vma = FindVMA(virtual_addr); ASSERT_MSG(vma != vma_map.end(), "Attempted to access invalid GPU address {:#x}", virtual_addr); - const u64 clamped_size = - std::min(size, vma->second.base + vma->second.size - virtual_addr); + u64 clamped_size = vma->second.base + vma->second.size - virtual_addr; + ++vma; + + // Keep adding to the size while there is contigious virtual address space. + while (!vma->second.IsFree() && clamped_size < size) { + clamped_size += vma->second.size; + ++vma; + } + clamped_size = std::min(clamped_size, size); + if (size != clamped_size) { LOG_WARNING(Kernel_Vmm, "Clamped requested buffer range addr={:#x}, size={:#x} to {:#x}", virtual_addr, size, clamped_size); diff --git a/src/video_core/texture_cache/texture_cache.cpp b/src/video_core/texture_cache/texture_cache.cpp index 34bcb8511..d41ee57cc 100644 --- a/src/video_core/texture_cache/texture_cache.cpp +++ b/src/video_core/texture_cache/texture_cache.cpp @@ -240,8 +240,8 @@ std::tuple TextureCache::ResolveOverlap(const ImageInfo& imag if (auto mip = tex_cache_image.info.MipOf(image_info); mip >= 0) { if (auto slice = tex_cache_image.info.SliceOf(image_info, mip); slice >= 0) { if (tex_cache_image.binding.is_target) { - // We have a larger image created and a separate one, representing a subres of it, - // bound as render target. In this case we need to rebind render target. + // We have a larger image created and a separate one, representing a subres of + // it, bound as render target. In this case we need to rebind render target. tex_cache_image.binding.needs_rebind = 1u; if (merged_image_id) { GetImage(merged_image_id).binding.is_target = 1u;