VulkanSemaphorePair.cs 3.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using Avalonia.Platform;
  4. using Silk.NET.Vulkan;
  5. using Silk.NET.Vulkan.Extensions.KHR;
  6. using SilkNetDemo;
  7. namespace GpuInterop.VulkanDemo;
  8. class VulkanSemaphorePair : IDisposable
  9. {
  10. private readonly VulkanContext _resources;
  11. public unsafe VulkanSemaphorePair(VulkanContext resources, bool exportable)
  12. {
  13. _resources = resources;
  14. var semaphoreExportInfo = new ExportSemaphoreCreateInfo
  15. {
  16. SType = StructureType.ExportSemaphoreCreateInfo,
  17. HandleTypes = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
  18. ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit :
  19. ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
  20. };
  21. var semaphoreCreateInfo = new SemaphoreCreateInfo
  22. {
  23. SType = StructureType.SemaphoreCreateInfo,
  24. PNext = exportable ? &semaphoreExportInfo : null
  25. };
  26. resources.Api.CreateSemaphore(resources.Device, semaphoreCreateInfo, null, out var semaphore).ThrowOnError();
  27. ImageAvailableSemaphore = semaphore;
  28. resources.Api.CreateSemaphore(resources.Device, semaphoreCreateInfo, null, out semaphore).ThrowOnError();
  29. RenderFinishedSemaphore = semaphore;
  30. }
  31. public int ExportFd(bool renderFinished)
  32. {
  33. if (!_resources.Api.TryGetDeviceExtension<KhrExternalSemaphoreFd>(_resources.Instance, _resources.Device,
  34. out var ext))
  35. throw new InvalidOperationException();
  36. var info = new SemaphoreGetFdInfoKHR()
  37. {
  38. SType = StructureType.SemaphoreGetFDInfoKhr,
  39. Semaphore = renderFinished ? RenderFinishedSemaphore : ImageAvailableSemaphore,
  40. HandleType = ExternalSemaphoreHandleTypeFlags.OpaqueFDBit
  41. };
  42. ext.GetSemaphoreF(_resources.Device, info, out var fd).ThrowOnError();
  43. return fd;
  44. }
  45. public IntPtr ExportWin32(bool renderFinished)
  46. {
  47. if (!_resources.Api.TryGetDeviceExtension<KhrExternalSemaphoreWin32>(_resources.Instance, _resources.Device,
  48. out var ext))
  49. throw new InvalidOperationException();
  50. var info = new SemaphoreGetWin32HandleInfoKHR()
  51. {
  52. SType = StructureType.SemaphoreGetWin32HandleInfoKhr,
  53. Semaphore = renderFinished ? RenderFinishedSemaphore : ImageAvailableSemaphore,
  54. HandleType = ExternalSemaphoreHandleTypeFlags.OpaqueWin32Bit
  55. };
  56. ext.GetSemaphoreWin32Handle(_resources.Device, info, out var fd).ThrowOnError();
  57. return fd;
  58. }
  59. public IPlatformHandle Export(bool renderFinished)
  60. {
  61. if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
  62. return new PlatformHandle(ExportWin32(renderFinished),
  63. KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaqueNtHandle);
  64. return new PlatformHandle(new IntPtr(ExportFd(renderFinished)),
  65. KnownPlatformGraphicsExternalSemaphoreHandleTypes.VulkanOpaquePosixFileDescriptor);
  66. }
  67. internal Semaphore ImageAvailableSemaphore { get; }
  68. internal Semaphore RenderFinishedSemaphore { get; }
  69. public unsafe void Dispose()
  70. {
  71. _resources.Api.DestroySemaphore(_resources.Device, ImageAvailableSemaphore, null);
  72. _resources.Api.DestroySemaphore(_resources.Device, RenderFinishedSemaphore, null);
  73. }
  74. }