Move DescriptorSetManager to PipelineLayoutCacheEntry to allow different pool sizes per layout

This commit is contained in:
Gabriel A 2024-03-17 19:16:49 -03:00
commit b3a2f02f60
3 changed files with 42 additions and 40 deletions

View file

@ -6,7 +6,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
class DescriptorSetManager : IDisposable class DescriptorSetManager : IDisposable
{ {
public const uint MaxSets = 16; public const uint MaxSets = 8;
public class DescriptorPoolHolder : IDisposable public class DescriptorPoolHolder : IDisposable
{ {

View file

@ -8,14 +8,7 @@ namespace Ryujinx.Graphics.Vulkan
{ {
class PipelineLayoutCacheEntry class PipelineLayoutCacheEntry
{ {
// Those were adjusted based on current descriptor usage and the descriptor counts usually used on pipeline layouts. private const int MaxPoolSizesPerSet = 8;
// It might be a good idea to tweak them again if those change, or maybe find a way to calculate an optimal value dynamically.
private const uint DefaultUniformBufferPoolCapacity = 19 * DescriptorSetManager.MaxSets;
private const uint DefaultStorageBufferPoolCapacity = 16 * DescriptorSetManager.MaxSets;
private const uint DefaultTexturePoolCapacity = 1024 * DescriptorSetManager.MaxSets;
private const uint DefaultImagePoolCapacity = 8 * DescriptorSetManager.MaxSets;
private const int MaxPoolSizesPerSet = 2;
private readonly VulkanRenderer _gd; private readonly VulkanRenderer _gd;
private readonly Device _device; private readonly Device _device;
@ -24,6 +17,9 @@ namespace Ryujinx.Graphics.Vulkan
public PipelineLayout PipelineLayout { get; } public PipelineLayout PipelineLayout { get; }
private readonly int[] _consumedDescriptorsPerSet; private readonly int[] _consumedDescriptorsPerSet;
private readonly DescriptorPoolSize[][] _poolSizes;
private readonly DescriptorSetManager _descriptorSetManager;
private readonly List<Auto<DescriptorSetCollection>>[][] _dsCache; private readonly List<Auto<DescriptorSetCollection>>[][] _dsCache;
private List<Auto<DescriptorSetCollection>>[] _currentDsCache; private List<Auto<DescriptorSetCollection>>[] _currentDsCache;
@ -65,6 +61,9 @@ namespace Ryujinx.Graphics.Vulkan
(DescriptorSetLayouts, PipelineLayout) = PipelineLayoutFactory.Create(gd, device, setDescriptors, usePushDescriptors); (DescriptorSetLayouts, PipelineLayout) = PipelineLayoutFactory.Create(gd, device, setDescriptors, usePushDescriptors);
_consumedDescriptorsPerSet = new int[setDescriptors.Count]; _consumedDescriptorsPerSet = new int[setDescriptors.Count];
_poolSizes = new DescriptorPoolSize[setDescriptors.Count][];
Span<DescriptorPoolSize> poolSizes = stackalloc DescriptorPoolSize[MaxPoolSizesPerSet];
for (int setIndex = 0; setIndex < setDescriptors.Count; setIndex++) for (int setIndex = 0; setIndex < setDescriptors.Count; setIndex++)
{ {
@ -76,6 +75,7 @@ namespace Ryujinx.Graphics.Vulkan
} }
_consumedDescriptorsPerSet[setIndex] = count; _consumedDescriptorsPerSet[setIndex] = count;
_poolSizes[setIndex] = GetDescriptorPoolSizes(poolSizes, setDescriptors[setIndex], DescriptorSetManager.MaxSets).ToArray();
} }
if (usePushDescriptors) if (usePushDescriptors)
@ -83,6 +83,8 @@ namespace Ryujinx.Graphics.Vulkan
_pdDescriptors = setDescriptors[0]; _pdDescriptors = setDescriptors[0];
_pdTemplates = new(); _pdTemplates = new();
} }
_descriptorSetManager = new DescriptorSetManager(_device, setDescriptors.Count);
} }
public void UpdateCommandBufferIndex(int commandBufferIndex) public void UpdateCommandBufferIndex(int commandBufferIndex)
@ -105,17 +107,12 @@ namespace Ryujinx.Graphics.Vulkan
int index = _dsCacheCursor[setIndex]++; int index = _dsCacheCursor[setIndex]++;
if (index == list.Count) if (index == list.Count)
{ {
Span<DescriptorPoolSize> poolSizes = stackalloc DescriptorPoolSize[MaxPoolSizesPerSet]; var dsc = _descriptorSetManager.AllocateDescriptorSet(
poolSizes = GetDescriptorPoolSizes(poolSizes, setIndex);
int consumedDescriptors = _consumedDescriptorsPerSet[setIndex];
var dsc = _gd.DescriptorSetManager.AllocateDescriptorSet(
_gd.Api, _gd.Api,
DescriptorSetLayouts[setIndex], DescriptorSetLayouts[setIndex],
poolSizes, _poolSizes[setIndex],
setIndex, setIndex,
consumedDescriptors, _consumedDescriptorsPerSet[setIndex],
false); false);
list.Add(dsc); list.Add(dsc);
@ -127,29 +124,36 @@ namespace Ryujinx.Graphics.Vulkan
return list[index]; return list[index];
} }
private static Span<DescriptorPoolSize> GetDescriptorPoolSizes(Span<DescriptorPoolSize> output, int setIndex) private static Span<DescriptorPoolSize> GetDescriptorPoolSizes(Span<DescriptorPoolSize> output, ResourceDescriptorCollection setDescriptor, uint multiplier)
{ {
int count = 1; int count = 0;
switch (setIndex) for (int index = 0; index < setDescriptor.Descriptors.Count; index++)
{ {
case PipelineBase.UniformSetIndex: ResourceDescriptor descriptor = setDescriptor.Descriptors[index];
output[0] = new(DescriptorType.UniformBuffer, DefaultUniformBufferPoolCapacity); DescriptorType descriptorType = descriptor.Type.Convert();
break;
case PipelineBase.StorageSetIndex: bool found = false;
output[0] = new(DescriptorType.StorageBuffer, DefaultStorageBufferPoolCapacity);
break; for (int poolSizeIndex = 0; poolSizeIndex < count; poolSizeIndex++)
case PipelineBase.TextureSetIndex: {
output[0] = new(DescriptorType.CombinedImageSampler, DefaultTexturePoolCapacity); if (output[poolSizeIndex].Type == descriptorType)
output[1] = new(DescriptorType.UniformTexelBuffer, DefaultTexturePoolCapacity); {
count = 2; output[poolSizeIndex].DescriptorCount += (uint)descriptor.Count * multiplier;
break; found = true;
case PipelineBase.ImageSetIndex:
output[0] = new(DescriptorType.StorageImage, DefaultImagePoolCapacity);
output[1] = new(DescriptorType.StorageTexelBuffer, DefaultImagePoolCapacity);
count = 2;
break; break;
} }
}
if (!found)
{
output[count++] = new DescriptorPoolSize()
{
Type = descriptorType,
DescriptorCount = (uint)descriptor.Count,
};
}
}
return output[..count]; return output[..count];
} }
@ -206,6 +210,8 @@ namespace Ryujinx.Graphics.Vulkan
{ {
_gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null); _gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null);
} }
_descriptorSetManager.Dispose();
} }
} }

View file

@ -48,7 +48,6 @@ namespace Ryujinx.Graphics.Vulkan
internal MemoryAllocator MemoryAllocator { get; private set; } internal MemoryAllocator MemoryAllocator { get; private set; }
internal HostMemoryAllocator HostMemoryAllocator { get; private set; } internal HostMemoryAllocator HostMemoryAllocator { get; private set; }
internal CommandBufferPool CommandBufferPool { get; private set; } internal CommandBufferPool CommandBufferPool { get; private set; }
internal DescriptorSetManager DescriptorSetManager { get; private set; }
internal PipelineLayoutCache PipelineLayoutCache { get; private set; } internal PipelineLayoutCache PipelineLayoutCache { get; private set; }
internal BackgroundResources BackgroundResources { get; private set; } internal BackgroundResources BackgroundResources { get; private set; }
internal Action<Action> InterruptAction { get; private set; } internal Action<Action> InterruptAction { get; private set; }
@ -414,8 +413,6 @@ namespace Ryujinx.Graphics.Vulkan
CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex); CommandBufferPool = new CommandBufferPool(Api, _device, Queue, QueueLock, queueFamilyIndex);
DescriptorSetManager = new DescriptorSetManager(_device, PipelineBase.DescriptorSetLayouts);
PipelineLayoutCache = new PipelineLayoutCache(); PipelineLayoutCache = new PipelineLayoutCache();
BackgroundResources = new BackgroundResources(this, _device); BackgroundResources = new BackgroundResources(this, _device);
@ -935,7 +932,6 @@ namespace Ryujinx.Graphics.Vulkan
HelperShader.Dispose(); HelperShader.Dispose();
_pipeline.Dispose(); _pipeline.Dispose();
BufferManager.Dispose(); BufferManager.Dispose();
DescriptorSetManager.Dispose();
PipelineLayoutCache.Dispose(); PipelineLayoutCache.Dispose();
Barriers.Dispose(); Barriers.Dispose();