aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs')
-rw-r--r--src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs
new file mode 100644
index 00000000..2c966115
--- /dev/null
+++ b/src/Ryujinx.Graphics.Vulkan/PipelineLayoutCacheEntry.cs
@@ -0,0 +1,112 @@
+using Ryujinx.Graphics.GAL;
+using Silk.NET.Vulkan;
+using System.Collections.Generic;
+
+namespace Ryujinx.Graphics.Vulkan
+{
+ class PipelineLayoutCacheEntry
+ {
+ private readonly VulkanRenderer _gd;
+ private readonly Device _device;
+
+ public DescriptorSetLayout[] DescriptorSetLayouts { get; }
+ public PipelineLayout PipelineLayout { get; }
+
+ private readonly List<Auto<DescriptorSetCollection>>[][] _dsCache;
+ private readonly int[] _dsCacheCursor;
+ private int _dsLastCbIndex;
+
+ private PipelineLayoutCacheEntry(VulkanRenderer gd, Device device)
+ {
+ _gd = gd;
+ _device = device;
+
+ _dsCache = new List<Auto<DescriptorSetCollection>>[CommandBufferPool.MaxCommandBuffers][];
+
+ for (int i = 0; i < CommandBufferPool.MaxCommandBuffers; i++)
+ {
+ _dsCache[i] = new List<Auto<DescriptorSetCollection>>[PipelineBase.DescriptorSetLayouts];
+
+ for (int j = 0; j < PipelineBase.DescriptorSetLayouts; j++)
+ {
+ _dsCache[i][j] = new List<Auto<DescriptorSetCollection>>();
+ }
+ }
+
+ _dsCacheCursor = new int[PipelineBase.DescriptorSetLayouts];
+ }
+
+ public PipelineLayoutCacheEntry(VulkanRenderer gd, Device device, uint stages, bool usePd) : this(gd, device)
+ {
+ DescriptorSetLayouts = PipelineLayoutFactory.Create(gd, device, stages, usePd, out var pipelineLayout);
+ PipelineLayout = pipelineLayout;
+ }
+
+ public PipelineLayoutCacheEntry(VulkanRenderer gd, Device device, ShaderSource[] shaders) : this(gd, device)
+ {
+ DescriptorSetLayouts = PipelineLayoutFactory.CreateMinimal(gd, device, shaders, out var pipelineLayout);
+ PipelineLayout = pipelineLayout;
+ }
+
+ public Auto<DescriptorSetCollection> GetNewDescriptorSetCollection(
+ VulkanRenderer gd,
+ int commandBufferIndex,
+ int setIndex,
+ out bool isNew)
+ {
+ if (_dsLastCbIndex != commandBufferIndex)
+ {
+ _dsLastCbIndex = commandBufferIndex;
+
+ for (int i = 0; i < PipelineBase.DescriptorSetLayouts; i++)
+ {
+ _dsCacheCursor[i] = 0;
+ }
+ }
+
+ var list = _dsCache[commandBufferIndex][setIndex];
+ int index = _dsCacheCursor[setIndex]++;
+ if (index == list.Count)
+ {
+ var dsc = gd.DescriptorSetManager.AllocateDescriptorSet(gd.Api, DescriptorSetLayouts[setIndex]);
+ list.Add(dsc);
+ isNew = true;
+ return dsc;
+ }
+
+ isNew = false;
+ return list[index];
+ }
+
+ protected virtual unsafe void Dispose(bool disposing)
+ {
+ if (disposing)
+ {
+ for (int i = 0; i < _dsCache.Length; i++)
+ {
+ for (int j = 0; j < _dsCache[i].Length; j++)
+ {
+ for (int k = 0; k < _dsCache[i][j].Count; k++)
+ {
+ _dsCache[i][j][k].Dispose();
+ }
+
+ _dsCache[i][j].Clear();
+ }
+ }
+
+ _gd.Api.DestroyPipelineLayout(_device, PipelineLayout, null);
+
+ for (int i = 0; i < DescriptorSetLayouts.Length; i++)
+ {
+ _gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null);
+ }
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ }
+ }
+}