/ src / Ryujinx.Graphics.Vulkan / BackgroundResources.cs
BackgroundResources.cs
  1  using Silk.NET.Vulkan;
  2  using System;
  3  using System.Collections.Generic;
  4  using System.Threading;
  5  
  6  namespace Ryujinx.Graphics.Vulkan
  7  {
  8      class BackgroundResource : IDisposable
  9      {
 10          private readonly VulkanRenderer _gd;
 11          private Device _device;
 12  
 13          private CommandBufferPool _pool;
 14          private PersistentFlushBuffer _flushBuffer;
 15  
 16          public BackgroundResource(VulkanRenderer gd, Device device)
 17          {
 18              _gd = gd;
 19              _device = device;
 20          }
 21  
 22          public CommandBufferPool GetPool()
 23          {
 24              if (_pool == null)
 25              {
 26                  bool useBackground = _gd.BackgroundQueue.Handle != 0 && _gd.Vendor != Vendor.Amd;
 27                  Queue queue = useBackground ? _gd.BackgroundQueue : _gd.Queue;
 28                  object queueLock = useBackground ? _gd.BackgroundQueueLock : _gd.QueueLock;
 29  
 30                  lock (queueLock)
 31                  {
 32                      _pool = new CommandBufferPool(
 33                          _gd.Api,
 34                          _device,
 35                          queue,
 36                          queueLock,
 37                          _gd.QueueFamilyIndex,
 38                          _gd.IsQualcommProprietary,
 39                          isLight: true);
 40                  }
 41              }
 42  
 43              return _pool;
 44          }
 45  
 46          public PersistentFlushBuffer GetFlushBuffer()
 47          {
 48              _flushBuffer ??= new PersistentFlushBuffer(_gd);
 49  
 50              return _flushBuffer;
 51          }
 52  
 53          public void Dispose()
 54          {
 55              _pool?.Dispose();
 56              _flushBuffer?.Dispose();
 57          }
 58      }
 59  
 60      class BackgroundResources : IDisposable
 61      {
 62          private readonly VulkanRenderer _gd;
 63          private Device _device;
 64  
 65          private readonly Dictionary<Thread, BackgroundResource> _resources;
 66  
 67          public BackgroundResources(VulkanRenderer gd, Device device)
 68          {
 69              _gd = gd;
 70              _device = device;
 71  
 72              _resources = new Dictionary<Thread, BackgroundResource>();
 73          }
 74  
 75          private void Cleanup()
 76          {
 77              lock (_resources)
 78              {
 79                  foreach (KeyValuePair<Thread, BackgroundResource> tuple in _resources)
 80                  {
 81                      if (!tuple.Key.IsAlive)
 82                      {
 83                          tuple.Value.Dispose();
 84                          _resources.Remove(tuple.Key);
 85                      }
 86                  }
 87              }
 88          }
 89  
 90          public BackgroundResource Get()
 91          {
 92              Thread thread = Thread.CurrentThread;
 93  
 94              lock (_resources)
 95              {
 96                  if (!_resources.TryGetValue(thread, out BackgroundResource resource))
 97                  {
 98                      Cleanup();
 99  
100                      resource = new BackgroundResource(_gd, _device);
101  
102                      _resources[thread] = resource;
103                  }
104  
105                  return resource;
106              }
107          }
108  
109          public void Dispose()
110          {
111              lock (_resources)
112              {
113                  foreach (var resource in _resources.Values)
114                  {
115                      resource.Dispose();
116                  }
117              }
118          }
119      }
120  }