From 77e279721923e9dd476a4f815e05062014cf4971 Mon Sep 17 00:00:00 2001 From: PixelyIon Date: Sun, 6 Mar 2022 21:18:54 +0530 Subject: [PATCH] Delete expired `weak_ptr`s for Texture/Buffer views A large amount of Texture/Buffer views would expire before reuse could occur in `Texture::GetView`/`Buffer::GetView`. These can lead to a substantial memory allocation given enough time and they are now deleted during the lookup while iterating on all entries. It should be noted that there are a lot of duplicate views that don't live long enough to be reused and the ultimate solution here is to make those views live long enough to be reused. --- app/src/main/cpp/skyline/gpu/buffer.cpp | 8 ++++++-- app/src/main/cpp/skyline/gpu/texture/texture.cpp | 8 ++++++-- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/app/src/main/cpp/skyline/gpu/buffer.cpp b/app/src/main/cpp/skyline/gpu/buffer.cpp index 62777ef7..7ff5c92e 100644 --- a/app/src/main/cpp/skyline/gpu/buffer.cpp +++ b/app/src/main/cpp/skyline/gpu/buffer.cpp @@ -172,10 +172,14 @@ namespace skyline::gpu { } std::shared_ptr Buffer::GetView(vk::DeviceSize offset, vk::DeviceSize range, vk::Format format) { - for (const auto &viewWeak : views) { - auto view{viewWeak.lock()}; + for (auto viewIt{views.begin()}; viewIt != views.end();) { + auto view{viewIt->lock()}; if (view && view->offset == offset && view->range == range && view->format == format) return view; + else if (!view) + viewIt = views.erase(viewIt); + else + ++viewIt; } auto view{std::make_shared(shared_from_this(), offset, range, format)}; diff --git a/app/src/main/cpp/skyline/gpu/texture/texture.cpp b/app/src/main/cpp/skyline/gpu/texture/texture.cpp index 5b9ba371..106e64ec 100644 --- a/app/src/main/cpp/skyline/gpu/texture/texture.cpp +++ b/app/src/main/cpp/skyline/gpu/texture/texture.cpp @@ -515,10 +515,14 @@ namespace skyline::gpu { } std::shared_ptr Texture::GetView(vk::ImageViewType type, vk::ImageSubresourceRange range, texture::Format pFormat, vk::ComponentMapping mapping) { - for (const auto &viewWeak : views) { - auto view{viewWeak.lock()}; + for (auto viewIt{views.begin()}; viewIt != views.end();) { + auto view{viewIt->lock()}; if (view && type == view->type && pFormat == view->format && range == view->range && mapping == view->mapping) return view; + else if (!view) + viewIt = views.erase(viewIt); + else + ++viewIt; } auto view{std::make_shared(shared_from_this(), type, range, pFormat, mapping)};