From 32450d45de7889318e0f289fc52b3fffc62edf60 Mon Sep 17 00:00:00 2001
From: Mary <mary@mary.zone>
Date: Wed, 15 Feb 2023 07:50:26 +0100
Subject: [PATCH] vulkan: Clean up MemoryAllocator (#4418)

This started as an attempt to remove vkGetPhysicalDeviceMemoryProperties
in FindSuitableMemoryTypeIndex (As this could have some overhead and
shouldn't change at runtime) and turned in a little bigger cleanup.
---
 Ryujinx.Graphics.Vulkan/BufferManager.cs   |  6 ++---
 Ryujinx.Graphics.Vulkan/MemoryAllocator.cs | 26 ++++++++++------------
 Ryujinx.Graphics.Vulkan/TextureStorage.cs  |  5 ++---
 Ryujinx.Graphics.Vulkan/VulkanRenderer.cs  |  6 ++---
 4 files changed, 19 insertions(+), 24 deletions(-)

diff --git a/Ryujinx.Graphics.Vulkan/BufferManager.cs b/Ryujinx.Graphics.Vulkan/BufferManager.cs
index 9c50e6ff..49fdd75d 100644
--- a/Ryujinx.Graphics.Vulkan/BufferManager.cs
+++ b/Ryujinx.Graphics.Vulkan/BufferManager.cs
@@ -39,7 +39,6 @@ namespace Ryujinx.Graphics.Vulkan
             BufferUsageFlags.VertexBufferBit |
             BufferUsageFlags.TransformFeedbackBufferBitExt;
 
-        private readonly PhysicalDevice _physicalDevice;
         private readonly Device _device;
 
         private readonly IdList<BufferHolder> _buffers;
@@ -48,9 +47,8 @@ namespace Ryujinx.Graphics.Vulkan
 
         public StagingBuffer StagingBuffer { get; }
 
-        public BufferManager(VulkanRenderer gd, PhysicalDevice physicalDevice, Device device)
+        public BufferManager(VulkanRenderer gd, Device device)
         {
-            _physicalDevice = physicalDevice;
             _device = device;
             _buffers = new IdList<BufferHolder>();
             StagingBuffer = new StagingBuffer(gd, this);
@@ -114,7 +112,7 @@ namespace Ryujinx.Graphics.Vulkan
                 allocateFlagsAlt = DefaultBufferMemoryAltFlags;
             }
 
-            var allocation = gd.MemoryAllocator.AllocateDeviceMemory(_physicalDevice, requirements, allocateFlags, allocateFlagsAlt);
+            var allocation = gd.MemoryAllocator.AllocateDeviceMemory(requirements, allocateFlags, allocateFlagsAlt);
 
             if (allocation.Memory.Handle == 0UL)
             {
diff --git a/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs b/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs
index 83c0a324..e4dcd916 100644
--- a/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs
+++ b/Ryujinx.Graphics.Vulkan/MemoryAllocator.cs
@@ -9,34 +9,36 @@ namespace Ryujinx.Graphics.Vulkan
         private ulong MaxDeviceMemoryUsageEstimate = 16UL * 1024 * 1024 * 1024;
 
         private readonly Vk _api;
+        private readonly PhysicalDevice _physicalDevice;
         private readonly Device _device;
         private readonly List<MemoryAllocatorBlockList> _blockLists;
+        private readonly int _blockAlignment;
+        private readonly PhysicalDeviceMemoryProperties _physicalDeviceMemoryProperties;
 
-        private int _blockAlignment;
-
-        public MemoryAllocator(Vk api, Device device, uint maxMemoryAllocationCount)
+        public MemoryAllocator(Vk api, PhysicalDevice physicalDevice, Device device, uint maxMemoryAllocationCount)
         {
             _api = api;
+            _physicalDevice = physicalDevice;
             _device = device;
             _blockLists = new List<MemoryAllocatorBlockList>();
             _blockAlignment = (int)Math.Min(int.MaxValue, MaxDeviceMemoryUsageEstimate / (ulong)maxMemoryAllocationCount);
+
+            _api.GetPhysicalDeviceMemoryProperties(_physicalDevice, out _physicalDeviceMemoryProperties);
         }
 
         public MemoryAllocation AllocateDeviceMemory(
-            PhysicalDevice physicalDevice,
             MemoryRequirements requirements,
             MemoryPropertyFlags flags = 0)
         {
-            return AllocateDeviceMemory(physicalDevice, requirements, flags, flags);
+            return AllocateDeviceMemory(requirements, flags, flags);
         }
 
         public MemoryAllocation AllocateDeviceMemory(
-            PhysicalDevice physicalDevice,
             MemoryRequirements requirements,
             MemoryPropertyFlags flags,
             MemoryPropertyFlags alternativeFlags)
         {
-            int memoryTypeIndex = FindSuitableMemoryTypeIndex(_api, physicalDevice, requirements.MemoryTypeBits, flags, alternativeFlags);
+            int memoryTypeIndex = FindSuitableMemoryTypeIndex(requirements.MemoryTypeBits, flags, alternativeFlags);
             if (memoryTypeIndex < 0)
             {
                 return default;
@@ -65,20 +67,16 @@ namespace Ryujinx.Graphics.Vulkan
             return newBl.Allocate(size, alignment, map);
         }
 
-        private static int FindSuitableMemoryTypeIndex(
-            Vk api,
-            PhysicalDevice physicalDevice,
+        private int FindSuitableMemoryTypeIndex(
             uint memoryTypeBits,
             MemoryPropertyFlags flags,
             MemoryPropertyFlags alternativeFlags)
         {
             int bestCandidateIndex = -1;
 
-            api.GetPhysicalDeviceMemoryProperties(physicalDevice, out var properties);
-
-            for (int i = 0; i < properties.MemoryTypeCount; i++)
+            for (int i = 0; i < _physicalDeviceMemoryProperties.MemoryTypeCount; i++)
             {
-                var type = properties.MemoryTypes[i];
+                var type = _physicalDeviceMemoryProperties.MemoryTypes[i];
 
                 if ((memoryTypeBits & (1 << i)) != 0)
                 {
diff --git a/Ryujinx.Graphics.Vulkan/TextureStorage.cs b/Ryujinx.Graphics.Vulkan/TextureStorage.cs
index 92209997..03a47a09 100644
--- a/Ryujinx.Graphics.Vulkan/TextureStorage.cs
+++ b/Ryujinx.Graphics.Vulkan/TextureStorage.cs
@@ -55,7 +55,6 @@ namespace Ryujinx.Graphics.Vulkan
 
         public unsafe TextureStorage(
             VulkanRenderer gd,
-            PhysicalDevice physicalDevice,
             Device device,
             TextureCreateInfo info,
             float scaleFactor,
@@ -118,7 +117,7 @@ namespace Ryujinx.Graphics.Vulkan
             if (foreignAllocation == null)
             {
                 gd.Api.GetImageMemoryRequirements(device, _image, out var requirements);
-                var allocation = gd.MemoryAllocator.AllocateDeviceMemory(physicalDevice, requirements, DefaultImageMemoryFlags);
+                var allocation = gd.MemoryAllocator.AllocateDeviceMemory(requirements, DefaultImageMemoryFlags);
 
                 if (allocation.Memory.Handle == 0UL)
                 {
@@ -173,7 +172,7 @@ namespace Ryujinx.Graphics.Vulkan
 
                 var info = NewCreateInfoWith(ref _info, format, _info.BytesPerPixel);
 
-                storage = new TextureStorage(_gd, default, _device, info, ScaleFactor, _allocationAuto);
+                storage = new TextureStorage(_gd, _device, info, ScaleFactor, _allocationAuto);
 
                 _aliasedStorages.Add(format, storage);
             }
diff --git a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
index 92dec7a1..595e033c 100644
--- a/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
+++ b/Ryujinx.Graphics.Vulkan/VulkanRenderer.cs
@@ -280,7 +280,7 @@ namespace Ryujinx.Graphics.Vulkan
                 supportedSampleCounts,
                 portabilityFlags);
 
-            MemoryAllocator = new MemoryAllocator(Api, _device, properties.Limits.MaxMemoryAllocationCount);
+            MemoryAllocator = new MemoryAllocator(Api, _physicalDevice, _device, properties.Limits.MaxMemoryAllocationCount);
 
             CommandBufferPool = VulkanInitialization.CreateCommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex);
 
@@ -290,7 +290,7 @@ namespace Ryujinx.Graphics.Vulkan
 
             BackgroundResources = new BackgroundResources(this, _device);
 
-            BufferManager = new BufferManager(this, _physicalDevice, _device);
+            BufferManager = new BufferManager(this, _device);
 
             _syncManager = new SyncManager(this, _device);
             _pipeline = new PipelineFull(this, _device);
@@ -388,7 +388,7 @@ namespace Ryujinx.Graphics.Vulkan
 
         internal TextureStorage CreateTextureStorage(TextureCreateInfo info, float scale)
         {
-            return new TextureStorage(this, _physicalDevice, _device, info, scale);
+            return new TextureStorage(this, _device, info, scale);
         }
 
         public void DeleteBuffer(BufferHandle buffer)