aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorriperiperi <rhy3756547@hotmail.com>2022-10-19 00:52:08 +0100
committerGitHub <noreply@github.com>2022-10-18 23:52:08 +0000
commit6e92b7a3782f2b46c57c833d68087d7f5b1feb80 (patch)
treedd3e6bfae43024b349431e6beaad9fc3a530b2ea
parent9b852c74816d3f9b76e51af479d32d1cd6498c30 (diff)
Dispose Vulkan TextureStorage when views hit 0 instead of immediately (#3738)1.1.312
Due to the `using` statement being scoped to the `CreateTextureView` method, `TextureStorage` would be disposed as soon as the view was returned. This was largely fine as the TextureStorage resources were being kept alive by the views holding their own references to them, but it also meant that dispose is only called as soon as the texture is created. Aliased Storages are TextureStorages created with the same allocation as another TextureStorage, if they have to be aliased as another format. We keep track of a TextureStorage's `_aliasedStorages` as they are created, and dispose them when the TextureStorage is disposed... ...except it is disposed immediately, before any aliased storages are even created. The aliased storages added after this will never be disposed. This PR attempts to fix this by disposing TextureStorage when its view count reaches 0. The other use of texture storage - the D32S8 blit - still manually disposes the storage, but regular uses created via the GAL are now disposed by the view count. I think this makes the most sense, as otherwise in the future this behaviour might be forgotton and more things could be added to the Dispose() method that don't work due to it not actually calling at the right time. This should improve memory leaks in Super Mario Odyssey, most noticeable when resolution scaling. The memory usage of the game is still wildly unpredictable due to how it interacts with the texture cache, but now it shouldn't get considerably longer as you play... I hope. I've seen it typically recover back to the same level occasionally, though it can spike significantly. Please test a bunch of games on multiple GPUs to make sure this doesn't break anything.
-rw-r--r--Ryujinx.Graphics.Vulkan/TextureStorage.cs2
-rw-r--r--Ryujinx.Graphics.Vulkan/VulkanRenderer.cs2
2 files changed, 3 insertions, 1 deletions
diff --git a/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/Ryujinx.Graphics.Vulkan/TextureStorage.cs
index b2cbd602..c4ebaef3 100644
--- a/Ryujinx.Graphics.Vulkan/TextureStorage.cs
+++ b/Ryujinx.Graphics.Vulkan/TextureStorage.cs
@@ -480,6 +480,8 @@ namespace Ryujinx.Graphics.Vulkan
if (--_viewsCount == 0)
{
_gd.PipelineInternal?.FlushCommandsIfWeightExceeding(_imageAuto, _size);
+
+ Dispose();
}
}
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index d92fff49..96c7da6c 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -310,7 +310,7 @@ namespace Ryujinx.Graphics.Vulkan
internal TextureView CreateTextureView(TextureCreateInfo info, float scale)
{
// This should be disposed when all views are destroyed.
- using var storage = CreateTextureStorage(info, scale);
+ var storage = CreateTextureStorage(info, scale);
return storage.CreateView(info, 0, 0);
}