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 }