From 65d5a3bce5779477fa8ccdfb837b80d662ec0b6f Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Mon, 28 Mar 2022 13:07:53 +0530 Subject: [PATCH] Align all `Buffer`s to page boundary We have support for overlapping buffers which allows us to merge a lot of smaller buffers located on a single page into a single larger buffer which allows for better performance. It additionally ensures that all host buffers match the alignment guarantees of the guest and adequately fulfill host alignment requirements. --- app/src/main/cpp/skyline/gpu/buffer_manager.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/buffer_manager.cpp b/app/src/main/cpp/skyline/gpu/buffer_manager.cpp index d93e0c1e..3866a84f 100644 --- a/app/src/main/cpp/skyline/gpu/buffer_manager.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer_manager.cpp @@ -13,6 +13,15 @@ namespace skyline::gpu { } BufferView BufferManager::FindOrCreate(GuestBuffer guestMapping, const std::shared_ptr &cycle) { + /* + * We align the buffer to the page boundary to ensure that: + * 1) Any buffer view has the same alignment guarantees as on the guest, this is required for UBOs, SSBOs and Texel buffers + * 2) We can coalesce a lot of tiny buffers into a single large buffer covering an entire page, this is often the case for index buffers and vertex buffers + */ + auto alignedStart{util::AlignDown(guestMapping.begin().base(), PAGE_SIZE)}, alignedEnd{util::AlignUp(guestMapping.end().base(), PAGE_SIZE)}; + vk::DeviceSize offset{static_cast(guestMapping.begin().base() - alignedStart)}, size{guestMapping.size()}; + guestMapping = span{alignedStart, alignedEnd}; + std::scoped_lock lock(mutex); // Lookup for any buffers overlapping with the supplied guest mapping @@ -26,7 +35,7 @@ namespace skyline::gpu { if (buffer->guest.begin() <= guestMapping.begin() && buffer->guest.end() >= guestMapping.end()) { // If we find a buffer which can entirely fit the guest mapping, we can just return a view into it std::scoped_lock bufferLock{*buffer}; - return buffer->GetView(static_cast(guestMapping.begin() - buffer->guest.begin()), guestMapping.size()); + return buffer->GetView(static_cast(guestMapping.begin() - buffer->guest.begin()) + offset, size); } } @@ -70,6 +79,6 @@ namespace skyline::gpu { buffers.insert(std::lower_bound(buffers.begin(), buffers.end(), newBuffer->guest.end().base(), BufferLessThan), newBuffer); - return newBuffer->GetView(static_cast(guestMapping.begin() - newBuffer->guest.begin()), guestMapping.size()); + return newBuffer->GetView(static_cast(guestMapping.begin() - newBuffer->guest.begin()) + offset, size); } }