PipelineLayoutCacheEntry.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. using Ryujinx.Graphics.GAL;
  2. using Silk.NET.Vulkan;
  3. using System.Collections.Generic;
  4. namespace Ryujinx.Graphics.Vulkan
  5. {
  6. class PipelineLayoutCacheEntry
  7. {
  8. private readonly VulkanRenderer _gd;
  9. private readonly Device _device;
  10. public DescriptorSetLayout[] DescriptorSetLayouts { get; }
  11. public PipelineLayout PipelineLayout { get; }
  12. private readonly List<Auto<DescriptorSetCollection>>[][] _dsCache;
  13. private readonly int[] _dsCacheCursor;
  14. private int _dsLastCbIndex;
  15. private PipelineLayoutCacheEntry(VulkanRenderer gd, Device device)
  16. {
  17. _gd = gd;
  18. _device = device;
  19. _dsCache = new List<Auto<DescriptorSetCollection>>[CommandBufferPool.MaxCommandBuffers][];
  20. for (int i = 0; i < CommandBufferPool.MaxCommandBuffers; i++)
  21. {
  22. _dsCache[i] = new List<Auto<DescriptorSetCollection>>[PipelineBase.DescriptorSetLayouts];
  23. for (int j = 0; j < PipelineBase.DescriptorSetLayouts; j++)
  24. {
  25. _dsCache[i][j] = new List<Auto<DescriptorSetCollection>>();
  26. }
  27. }
  28. _dsCacheCursor = new int[PipelineBase.DescriptorSetLayouts];
  29. }
  30. public PipelineLayoutCacheEntry(VulkanRenderer gd, Device device, uint stages, bool usePd) : this(gd, device)
  31. {
  32. DescriptorSetLayouts = PipelineLayoutFactory.Create(gd, device, stages, usePd, out var pipelineLayout);
  33. PipelineLayout = pipelineLayout;
  34. }
  35. public PipelineLayoutCacheEntry(VulkanRenderer gd, Device device, ShaderSource[] shaders) : this(gd, device)
  36. {
  37. DescriptorSetLayouts = PipelineLayoutFactory.CreateMinimal(gd, device, shaders, out var pipelineLayout);
  38. PipelineLayout = pipelineLayout;
  39. }
  40. public Auto<DescriptorSetCollection> GetNewDescriptorSetCollection(
  41. VulkanRenderer gd,
  42. int commandBufferIndex,
  43. int setIndex,
  44. out bool isNew)
  45. {
  46. if (_dsLastCbIndex != commandBufferIndex)
  47. {
  48. _dsLastCbIndex = commandBufferIndex;
  49. for (int i = 0; i < PipelineBase.DescriptorSetLayouts; i++)
  50. {
  51. _dsCacheCursor[i] = 0;
  52. }
  53. }
  54. var list = _dsCache[commandBufferIndex][setIndex];
  55. int index = _dsCacheCursor[setIndex]++;
  56. if (index == list.Count)
  57. {
  58. var dsc = gd.DescriptorSetManager.AllocateDescriptorSet(gd.Api, DescriptorSetLayouts[setIndex]);
  59. list.Add(dsc);
  60. isNew = true;
  61. return dsc;
  62. }
  63. isNew = false;
  64. return list[index];
  65. }
  66. protected virtual unsafe void Dispose(bool disposing)
  67. {
  68. if (disposing)
  69. {
  70. for (int i = 0; i < _dsCache.Length; i++)
  71. {
  72. for (int j = 0; j < _dsCache[i].Length; j++)
  73. {
  74. for (int k = 0; k < _dsCache[i][j].Count; k++)
  75. {
  76. _dsCache[i][j][k].Dispose();
  77. }
  78. _dsCache[i][j].Clear();
  79. }
  80. }
  81. _gd.Api.DestroyPipelineLayout(_device, PipelineLayout, null);
  82. for (int i = 0; i < DescriptorSetLayouts.Length; i++)
  83. {
  84. _gd.Api.DestroyDescriptorSetLayout(_device, DescriptorSetLayouts[i], null);
  85. }
  86. }
  87. }
  88. public void Dispose()
  89. {
  90. Dispose(true);
  91. }
  92. }
  93. }