FenceHolder.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. using Silk.NET.Vulkan;
  2. using System;
  3. using System.Threading;
  4. namespace Ryujinx.Graphics.Vulkan
  5. {
  6. class FenceHolder : IDisposable
  7. {
  8. private readonly Vk _api;
  9. private readonly Device _device;
  10. private Fence _fence;
  11. private int _referenceCount;
  12. private bool _disposed;
  13. public unsafe FenceHolder(Vk api, Device device)
  14. {
  15. _api = api;
  16. _device = device;
  17. var fenceCreateInfo = new FenceCreateInfo()
  18. {
  19. SType = StructureType.FenceCreateInfo
  20. };
  21. api.CreateFence(device, in fenceCreateInfo, null, out _fence).ThrowOnError();
  22. _referenceCount = 1;
  23. }
  24. public Fence GetUnsafe()
  25. {
  26. return _fence;
  27. }
  28. public Fence Get()
  29. {
  30. Interlocked.Increment(ref _referenceCount);
  31. return _fence;
  32. }
  33. public void Put()
  34. {
  35. if (Interlocked.Decrement(ref _referenceCount) == 0)
  36. {
  37. _api.DestroyFence(_device, _fence, Span<AllocationCallbacks>.Empty);
  38. _fence = default;
  39. }
  40. }
  41. public void Wait()
  42. {
  43. Span<Fence> fences = stackalloc Fence[]
  44. {
  45. _fence
  46. };
  47. FenceHelper.WaitAllIndefinitely(_api, _device, fences);
  48. }
  49. public bool IsSignaled()
  50. {
  51. Span<Fence> fences = stackalloc Fence[]
  52. {
  53. _fence
  54. };
  55. return FenceHelper.AllSignaled(_api, _device, fences);
  56. }
  57. public void Dispose()
  58. {
  59. if (!_disposed)
  60. {
  61. Put();
  62. _disposed = true;
  63. }
  64. }
  65. }
  66. }